home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 26 / Cream of the Crop 26.iso / os2 / pvm34b3.zip / pvm34b3 / pvm3 / src / pmsg.c < prev    next >
C/C++ Source or Header  |  1997-08-08  |  55KB  |  2,759 lines

  1.  
  2. static char rcsid[] =
  3.     "$Id: pmsg.c,v 1.7 1997/06/27 17:32:33 pvmsrc Exp $";
  4.  
  5. /*
  6.  *         PVM version 3.4:  Parallel Virtual Machine System
  7.  *               University of Tennessee, Knoxville TN.
  8.  *           Oak Ridge National Laboratory, Oak Ridge TN.
  9.  *                   Emory University, Atlanta GA.
  10.  *      Authors:  J. J. Dongarra, G. E. Fagg, M. Fischer
  11.  *          G. A. Geist, J. A. Kohl, R. J. Manchek, P. Mucci,
  12.  *         P. M. Papadopoulos, S. L. Scott, and V. S. Sunderam
  13.  *                   (C) 1997 All Rights Reserved
  14.  *
  15.  *                              NOTICE
  16.  *
  17.  * Permission to use, copy, modify, and distribute this software and
  18.  * its documentation for any purpose and without fee is hereby granted
  19.  * provided that the above copyright notice appear in all copies and
  20.  * that both the copyright notice and this permission notice appear in
  21.  * supporting documentation.
  22.  *
  23.  * Neither the Institutions (Emory University, Oak Ridge National
  24.  * Laboratory, and University of Tennessee) nor the Authors make any
  25.  * representations about the suitability of this software for any
  26.  * purpose.  This software is provided ``as is'' without express or
  27.  * implied warranty.
  28.  *
  29.  * PVM version 3 was funded in part by the U.S. Department of Energy,
  30.  * the National Science Foundation and the State of Tennessee.
  31.  */
  32.  
  33. /*
  34.  *    pmsg.c
  35.  *
  36.  *    Libpvm and pvmd message descriptors
  37.  *
  38. $Log: pmsg.c,v $
  39.  * Revision 1.7  1997/06/27  17:32:33  pvmsrc
  40.  * Updated for WIN32 header files & Authors.
  41.  *
  42.  * Revision 1.6  1997/04/30  21:32:14  pvmsrc
  43.  * SGI Compiler Warning Cleanup.
  44.  *     - fixed up return codes for trace message packing stuff.
  45.  *
  46.  * Revision 1.5  1997/04/09  14:40:32  pvmsrc
  47.  * PVM patches from the base 3.3.10 to 3.3.11 versions where applicable.
  48.  * Originals by Bob Manchek. Altered by Graham Fagg where required.
  49.  *
  50.  * Fixes bogus XDR en/decoding when passing short values.
  51.  * Original patch was meant for lpvmpack.c but code is now in pmsg.c
  52.  *
  53.  * Revision 1.4  1997/01/28  19:26:57  pvmsrc
  54.  * New Copyright Notice & Authors.
  55.  *
  56.  * Revision 1.3  1996/10/25  13:57:32  pvmsrc
  57.  * Replaced old #includes for protocol headers:
  58.  *     - <pvmsdpro.h>, "ddpro.h", "tdpro.h"
  59.  * With #include of new combined header:
  60.  *     - <pvmproto.h>
  61.  *
  62.  * Revision 1.2  1996/10/24  22:09:21  pvmsrc
  63.  * Moved #include "global.h" below other #include's for typing.
  64.  * Added #include <pvmtev.h> & new "lpvm.h" for tracing & libpvm globals.
  65.  * Added new user-defined trace event packing encoders:
  66.  *     - new enc_trc_init(), enc_trc_*() routines.
  67.  *     - new dec_trc_init(), dec_trc_*() routines.
  68.  *     - added new trace encoding vector in struct encvec encoders[],
  69.  *         with new selection in pmsg_setenc() for enc = 4 from
  70.  *         0x40000000 for user-defined tracing.
  71.  *
  72.  * Revision 1.1  1996/09/23  23:44:26  pvmsrc
  73.  * Initial revision
  74.  *
  75.  *
  76.  */
  77.  
  78. #include <stdio.h>
  79. #ifdef NEEDMENDIAN
  80. #include <machine/endian.h>
  81. #endif
  82. #ifdef NEEDENDIAN
  83. #include <endian.h>
  84. #endif
  85. #ifdef NEEDSENDIAN
  86. #include <sys/endian.h>
  87. #endif
  88. #ifndef WIN32
  89. #include <rpc/types.h>
  90. #include <rpc/xdr.h>
  91. #else
  92. #include "..\xdr\types.h"
  93. #include "..\xdr\xdr.h"
  94. #endif
  95. #include <pvm3.h>
  96. #include <pvmproto.h>
  97. #include "pvmalloc.h"
  98. #include "pvmfrag.h"
  99. #include "pmsg.h"
  100. #include "listmac.h"
  101. #include "bfunc.h"
  102. #include "lpvm.h"
  103. #include <pvmtev.h>
  104. #include "global.h"
  105.  
  106.  
  107. /***************
  108.  **  Globals  **
  109.  **           **
  110.  ***************/
  111.  
  112.  
  113. /***************
  114.  **  Private  **
  115.  **           **
  116.  ***************/
  117.  
  118. #ifdef    CLUMP_ALLOC
  119. #ifndef    PMSG_CLUMP
  120. #define    PMSG_CLUMP    50
  121. #endif
  122. static struct pmsg freepmsgs;            /* cache of pmsgs */
  123. static int numpmsgs = 0;
  124. #endif
  125.  
  126.  
  127. /****************************
  128. *  Generate data signature  *
  129. *                           *
  130. ****************************/
  131.  
  132. static int
  133. ibol(o, p, n)
  134.     int o;
  135.     char *p;
  136.     int n;
  137. {
  138.     int i, j;
  139.  
  140.     if (p[0] == 0) {
  141.         i = 0;    /* ll */
  142.     } else if (p[0] == n - 1) {
  143.         i = 3;    /* hh */
  144.     } else if (p[0] == n / 2) {
  145.         i = 2;    /* hl */
  146.     } else if (p[0] == n / 2 - 1) {
  147.         i = 1;    /* lh */
  148.     } else {
  149.         fprintf(stderr, "can't generate signature for my integer byte order\n");
  150.         abort();
  151.     }
  152.  
  153.     j = ffs(n) - 1;
  154. /*
  155.     printf(".%d%d.%d%d%d", (i & 2) ? 1 : 0, (i & 1) ? 1 : 0
  156.             (j & 4) ? 1 : 0, (j & 2) ? 1 : 0, (j & 1) ? 1 : 0);
  157. */
  158.     return ((i << 3) | j) << o;
  159. }
  160.  
  161.  
  162. /*
  163. *  (float)1.0 =
  164. *  IEEE single ll   00 00 80 3f
  165. *  IEEE double ll   00 00 00 00 00 00 f0 3f
  166. *  IEEE single hh   3f 80 00 00
  167. *  IEEE double hh   3f f0 00 00 00 00 00 00
  168. *  CRAY       (hh)  40 01 80 00 00 00 00 00
  169. *  Convex s   (hh)  40 80 00 00
  170. *  Convex d   (hh)  40 10 00 00 00 00 00 00
  171. *  IBM370 s
  172. *  IBM370 d
  173. *  VAX xxxx?
  174. */
  175.  
  176. struct floatsig {
  177.     int length;
  178.     unsigned char *bytes;
  179.     char *name;
  180. };
  181.  
  182. /*
  183. * signatures for float = 1.0 in hh byte order, all formats
  184. */
  185.  
  186. static unsigned char fs1[] = { 0x3f, 0x80, 0x00, 0x00 };
  187. static unsigned char fs2[] = { 0x3f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
  188. static unsigned char fs4[] = { 0x40, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00 };
  189. static unsigned char fs5[] = { 0x40, 0x80, 0x00, 0x00 };
  190. static unsigned char fs6[] = { 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
  191.  
  192. static struct floatsig thesigs[] = {
  193.     { 0, 0, "UNKNOWN" },
  194.     { 4, fs1, "IEEE_single" },
  195.     { 8, fs2, "IEEE_double" },
  196.     { 0, 0, "UNDEFINED" },
  197.     { 8, fs4, "Cray" },
  198.     { 4, fs5, "Convex_single" },
  199.     { 8, fs6, "Convex_double" },
  200.     { 0, 0, "UNDEFINED" },
  201.     { 0, 0, "UNDEFINED" },
  202.     { 0, 0, "UNDEFINED" },
  203.     { 0, 0, "UNDEFINED" },
  204.     { 0, 0, "UNDEFINED" },
  205.     { 0, 0, "UNDEFINED" },
  206.     { 0, 0, "UNDEFINED" },
  207.     { 0, 0, "UNDEFINED" },
  208.     { 0, 0, "UNDEFINED" },
  209. };
  210.  
  211.  
  212. static int
  213. fbol(o, p, n)
  214.     int o;
  215.     unsigned char *p;
  216.     int n;
  217. {
  218.     int i, j;
  219.  
  220.     for (i = 0; i < 16; i++) {
  221.         if (thesigs[i].length == n) {
  222.             for (j = 0; j < n; j++)
  223.                 if (p[j] != thesigs[i].bytes[j])
  224.                     break;
  225.             if (j == n)
  226.                 return ((3 << 4) | i) << o;
  227.  
  228.             for (j = 0; j < n; j++)
  229.                 if (p[n - 1 - j] != thesigs[i].bytes[j])
  230.                     break;
  231.             if (j == n)
  232.                 return i << o;
  233.         }
  234.     }
  235.     fprintf(stderr, "can't generate signature for my integer byte order\n");
  236.     abort();
  237.     return 0;
  238. }
  239.  
  240.  
  241. /*    pvm_getdsig()
  242. *
  243. *    Return data signature for executable, describing representations
  244. *    of integers and floats.
  245. *
  246. *    Bits:
  247. *    0:2  short int size
  248. *    3:4  short int byte order
  249. *    5:7  int size
  250. *    8:9  int byte order
  251. *   10:12  long int size
  252. *   13:14  long int byte order
  253. *   15:18  float format
  254. *   19:20  float byte order
  255. *   21:24  double float format
  256. *   25:26  double float byte order
  257. *   27:31  0
  258. *
  259. *    Sizes are 2 ** (0..7) bytes
  260. *    Byte order specifies overall order and half-folding:
  261. *        00  Little endian (e.g. 0 1 2 3)
  262. *        01  Little, but half-swapped (1 0 3 2 or 3 2 1 0 7 6 5 4)
  263. *        10  Big, but half swapped (2 3 0 1 or 4 5 6 7 0 1 2 3)
  264. *        11  Big endian (3 2 1 0)
  265. */
  266.  
  267. int
  268. pvmgetdsig()
  269. {
  270.     static int myfmt = -1;
  271.  
  272.     short i0;
  273.     int i1;
  274.     long i2;
  275.     float f0;
  276.     double f1;
  277.     int i, j;
  278.     int fmt;
  279.  
  280.     if (myfmt != -1)
  281.         return myfmt;
  282.  
  283.     fmt = 0;
  284.  
  285.     i0 = 0;
  286.     for (i = 0; i < sizeof(i0); i++)
  287.         i0 += (short)i << (i * 8);
  288.     fmt |= ibol(0, (char *) &i0, (int) sizeof(i0));
  289.  
  290.     i1 = 0;
  291.     for (i = 0; i < sizeof(i1); i++)
  292.         i1 += (int)i << (i * 8);
  293.     fmt |= ibol(5, (char *) &i1, (int) sizeof(i1));
  294.  
  295.     i2 = 0;
  296.     for (i = 0; i < sizeof(i2); i++)
  297.         i2 += (long)i << (i * 8);
  298.     fmt |= ibol(10, (char *) &i2, (int) sizeof(i2));
  299.  
  300.     f0 = 1.0;
  301.     fmt |= fbol(15, (unsigned char *) &f0, (int) sizeof(f0));
  302.  
  303.     f1 = 1.0;
  304.     fmt |= fbol(21, (unsigned char *) &f1, (int) sizeof(f1));
  305.  
  306.     myfmt = fmt;
  307.     return fmt;
  308. }
  309.  
  310.  
  311. /****************************
  312.  **  Message manipulation  **
  313.  **                        **
  314.  ****************************/
  315.  
  316.  
  317. static struct pmsg *
  318. pmsg_get()
  319. {
  320.     struct pmsg *mp;
  321.     int n;
  322.  
  323. #ifdef    CLUMP_ALLOC
  324.     if (numpmsgs == 0) {
  325.         freepmsgs.m_link = freepmsgs.m_rlink = &freepmsgs;
  326.         if (!(mp = TALLOC(PMSG_CLUMP, struct pmsg, "pmsgs")))
  327.             return (struct pmsg *)0;
  328.         for (n = PMSG_CLUMP; n-- > 0; ) {
  329.             LISTPUTBEFORE(&freepmsgs, mp, m_link, m_rlink);
  330.             mp++;
  331.         }
  332.         numpmsgs = PMSG_CLUMP;
  333.     }
  334.     numpmsgs--;
  335.     mp = freepmsgs.m_link;
  336.     LISTDELETE(mp, m_link, m_rlink);
  337.  
  338. #else
  339.     mp = TALLOC(1, struct pmsg, "pmsg");
  340. #endif
  341.  
  342.     return mp;
  343. }
  344.  
  345.  
  346. static void
  347. pmsg_put(mp)
  348.     struct pmsg *mp;
  349. {
  350. #ifdef    CLUMP_ALLOC
  351.     if (numpmsgs == 0)
  352.         freepmsgs.m_link = freepmsgs.m_rlink = &freepmsgs;
  353.     LISTPUTBEFORE(&freepmsgs, mp, m_link, m_rlink);
  354.     numpmsgs++;
  355.  
  356. #else
  357.     PVM_FREE(mp);
  358. #endif
  359. }
  360.  
  361.  
  362. /*    pmsg_new()
  363. *
  364. *    Create a new message.
  365. *    Returns pointer to message struct or NULL if no memory available.
  366. */
  367.  
  368. struct pmsg *
  369. pmsg_new(master)
  370.     int master;            /* true if a master (no data) node */
  371. {
  372.     struct pmsg *mp;
  373.  
  374.     if (!(mp = pmsg_get()))
  375.         goto fail;
  376.  
  377.     mp->m_ref = 1;
  378.     if (master) {
  379.         mp->m_link = mp->m_rlink = mp;
  380.         mp->m_frag = 0;
  381.     } else {
  382.         mp->m_link = mp->m_rlink = 0;
  383.         if (!(mp->m_frag = fr_new(0))) {
  384.             PVM_FREE(mp);
  385.             goto fail;
  386.         }
  387.     }
  388.     mp->m_codef = 0;
  389.     mp->m_cfrag = 0;
  390.     mp->m_mid = 0;
  391.     mp->m_len = 0;
  392.     mp->m_ctx = 0;
  393.     mp->m_tag = 0;
  394.     mp->m_wid = 0;
  395.     mp->m_src = 0;
  396.     mp->m_dst = 0;
  397.     mp->m_enc = 0;
  398.     mp->m_flag = 0;
  399.     mp->m_cpos = 0;
  400.     mp->m_crc = 0;
  401.     return mp;
  402.  
  403. fail:
  404.     return (struct pmsg *)0;
  405. }
  406.  
  407.  
  408. /*    pmsg_free()
  409. *
  410. *    Free a message or list of messages.  If m_frag is nonzero, this is
  411. *    a slave node; unlink and free it and its frag list.  Else, it's
  412. *    a master node; free all slave nodes too.
  413. */
  414.  
  415. static void
  416. pmsg_free(mp)
  417.     struct pmsg *mp;
  418. {
  419.     if (mp->m_frag) {    /* slave message */
  420.         if (mp->m_link && mp->m_rlink) {
  421.             LISTDELETE(mp, m_link, m_rlink);
  422.         }
  423.         fr_unref(mp->m_frag);
  424.  
  425.     } else {    /* master */
  426.         while (mp->m_link != mp)
  427.             pmsg_free(mp->m_link);
  428.     }
  429.     pmsg_put(mp);
  430. }
  431.  
  432.  
  433. /*    pmsg_unref()
  434. *
  435. *    Decrement message ref count, and free message if ref count reaches 0.
  436. */
  437.  
  438. void
  439. pmsg_unref(mp)
  440.     struct pmsg *mp;
  441. {
  442.     if (--mp->m_ref < 1)
  443.         pmsg_free(mp);
  444. }
  445.  
  446.  
  447. /*    pmsg_extend()
  448. *
  449. *    Add a new empty fragment to the end of a message.
  450. */
  451.  
  452. int
  453. pmsg_extend(mp)
  454.     struct pmsg *mp;
  455. {
  456.     struct frag *fp;
  457.  
  458.     if (fp = fr_new(pvmfrgsiz)) {
  459.         fp->fr_dat += MAXHDR;
  460.         LISTPUTBEFORE(mp->m_frag, fp, fr_link, fr_rlink);
  461.         return 0;
  462.     }
  463.     return PvmNoMem;
  464. }
  465.  
  466.  
  467. /*    pmsg_decmore()
  468. *
  469. *    Step to the next fragment to unpack.
  470. */
  471.  
  472. int
  473. pmsg_decmore(mp)
  474.     struct pmsg *mp;
  475. {
  476. #if 0
  477.     mp->m_cpos = 0;
  478.     if (mp->m_cfrag == mp->m_frag)        /* no message left */
  479.         return PvmNoData;
  480.     mp->m_cfrag = mp->m_cfrag->fr_link;
  481.     if (mp->m_cfrag == mp->m_frag)
  482.         return PvmNoData;
  483.     return 0;
  484. #endif
  485.     mp->m_cpos = 0;
  486.     if (mp->m_cfrag == mp->m_frag)        /* no message left */
  487.         return PvmNoData;
  488.     while ((mp->m_cfrag = mp->m_cfrag->fr_link) != mp->m_frag)
  489.         if (mp->m_cfrag->fr_len > 0)
  490.             break;
  491.     if (mp->m_cfrag == mp->m_frag)
  492.         return PvmNoData;
  493.     return 0;
  494. }
  495.  
  496.  
  497. /*    bytepk()
  498. *
  499. *    Insert a stream of bytes into message.  Allocate more fragments as
  500. *    necessary.
  501. *    Returns 0 else PvmNoMem if malloc fails.
  502. */
  503.  
  504. static int
  505. bytepk(mp, cp, num, siz, lnc)
  506.     struct pmsg *mp;
  507.     char *cp;            /* base of data */
  508.     int num;            /* num of chunks */
  509.     int siz;            /* size of chunk */
  510.     int lnc;            /* lead to next chunk */
  511. {
  512.     struct frag *fp;            /* working frag */
  513.     int togo;                    /* bytes left in chunk */
  514.     int r;                        /* bytes (space) left in frag */
  515.  
  516.     if (siz == lnc) {        /* if contiguous, treat as single chunk */
  517.         lnc = (siz *= num);
  518.         num = 1;
  519.     }
  520.     lnc -= siz;        /* now bytes between chunks */
  521.  
  522.     while (num-- > 0) {        /* copy chunks until done */
  523.  
  524.         for (togo = siz; togo > 0; ) {
  525.             fp = mp->m_frag->fr_rlink;
  526.             r = fp->fr_max - (fp->fr_dat - fp->fr_buf) - fp->fr_len;
  527.  
  528.             if (togo <= r) {    /* space in frag for entire chunk */
  529.                 BCOPY(cp, fp->fr_dat + fp->fr_len, togo);
  530.                 fp->fr_len += togo;
  531.                 cp += togo;
  532.                 togo = 0;
  533.  
  534.             } else {
  535.                 if (r > 0) {    /* space for part of chunk */
  536.                     BCOPY(cp, fp->fr_dat + fp->fr_len, r);
  537.                     fp->fr_len += r;
  538.                     togo -= r;
  539.                     cp += r;
  540.  
  541.                 } else {        /* no space, add new frag */
  542.                     if (r = pmsg_extend(mp))
  543.                         return r;
  544.                 }
  545.             }
  546.         }
  547.         cp += lnc;
  548.     }
  549.     return 0;
  550. }
  551.  
  552.  
  553. /*    byteupk()
  554. *
  555. *    Extract bytes from message, continuing to new fragments as necessary.
  556. *    Returns 0 else PvmNoData if end of message reached early.
  557. */
  558.  
  559. #ifdef IMA_CSPP
  560. static void pre_bcopy(unsigned int s1, unsigned int s2, int n);
  561. #endif
  562.  
  563. static int
  564. byteupk(mp, cp, num, siz, lnc)
  565.     struct pmsg *mp;
  566.     char *cp;            /* base of data */
  567.     int num;            /* num of chunks */
  568.     int siz;            /* size of chunk */
  569.     int lnc;            /* lead to next chunk */
  570. {
  571.     struct frag *fp;            /* working frag */
  572.     int togo;                    /* bytes left in chunk */
  573.     int r;                        /* bytes (data) left in frag */
  574. #ifdef IMA_CSPP
  575.     int diff_node = mp->m_flag & UB_DIFFNODE;
  576. #endif
  577.  
  578.     if (siz == lnc) {        /* if contiguous, treat as single chunk */
  579.         lnc = (siz *= num);
  580.         num = 1;
  581.     }
  582.     lnc -= siz;        /* now bytes between chunks */
  583.  
  584.     while (num-- > 0) {        /* copy chunks until done */
  585.  
  586.         for (togo = siz; togo > 0; ) {
  587.             fp = mp->m_cfrag;
  588.             r = fp->fr_len - mp->m_cpos;
  589.  
  590.             if (togo <= r) {    /* frag contains rest of chunk */
  591. #ifdef IMA_CSPP
  592.                 fp->fr_num_unpacked += togo;
  593.                 if (diff_node) {
  594.                     pre_bcopy((unsigned int)(fp->fr_dat + mp->m_cpos),
  595.                             (unsigned int)cp, togo);
  596.                 } else
  597. #endif
  598.                 BCOPY(fp->fr_dat + mp->m_cpos, cp, togo);
  599.                 mp->m_cpos += togo;
  600.                 cp += togo;
  601.                 togo = 0;
  602.  
  603.             } else {
  604.                 if (r > 0) {    /* frag contains part of chunk */
  605. #ifdef IMA_CSPP
  606.                     fp->fr_num_unpacked += r;
  607.                     if (diff_node) {
  608.                         pre_bcopy((unsigned int)(fp->fr_dat + mp->m_cpos),
  609.                                 (unsigned int)cp, r);
  610.                     } else
  611. #endif
  612.                     BCOPY(fp->fr_dat + mp->m_cpos, cp, r);
  613.                     mp->m_cpos += r;
  614.                     togo -= r;
  615.                     cp += r;
  616.  
  617.                 } else {        /* no space, add new frag */
  618.                     if (r = pmsg_decmore(mp))
  619.                         return r;
  620.                 }
  621.             }
  622.         }
  623.         cp += lnc;
  624.     }
  625.     return 0;
  626. }
  627.  
  628.  
  629. /***************************
  630.  **  Raw-format encoders  **
  631.  **                       **
  632.  ***************************/
  633.  
  634. /*    enc_raw_init()
  635. *
  636. *    Initialize a message buffer to pack raw data.
  637. */
  638.  
  639. static int
  640. enc_raw_init(mp)
  641.     struct pmsg *mp;
  642. {
  643.     if (!(mp->m_flag & MM_PACK)) {
  644.         mp->m_flag &= ~MM_UPACK;
  645.         mp->m_flag |= MM_PACK;
  646.         if (mp->m_frag->fr_link == mp->m_frag)
  647.             return pmsg_extend(mp);
  648.     }
  649.     return 0;
  650. }
  651.  
  652.  
  653. /*    dec_raw_init()
  654. *
  655. *    Initialize a message buffer to unpack raw data.
  656. */
  657.  
  658. static int
  659. dec_raw_init(mp)
  660.     struct pmsg *mp;
  661. {
  662.     if (!(mp->m_flag & MM_UPACK)) {
  663.         mp->m_flag &= ~MM_PACK;
  664.         mp->m_flag |= MM_UPACK;
  665.         mp->m_cfrag = mp->m_frag->fr_link;
  666.         mp->m_cpos = 0;
  667.     }
  668.     return 0;
  669. }
  670.  
  671.  
  672. /*    enc_raw_any()
  673. *
  674. *    Encode any data type into a raw format message buffer.
  675. */
  676.  
  677. static int
  678. enc_raw_any(mp, vp, cnt, std, siz)
  679.     struct pmsg *mp;
  680.     void *vp;
  681.     int cnt, std, siz;
  682. {
  683.     return bytepk(mp, (char*)vp, cnt, siz, std * siz);
  684. }
  685.  
  686.  
  687. /*    dec_raw_any()
  688. *
  689. *    Decode any data type from a raw format message buffer.
  690. */
  691.  
  692. static int
  693. dec_raw_any(mp, vp, cnt, std, siz)
  694.     struct pmsg *mp;
  695.     void *vp;
  696.     int cnt, std, siz;
  697. {
  698.     return byteupk(mp, (char*)vp, cnt, siz, std * siz);
  699. }
  700.  
  701.  
  702. /***************************
  703.  **  XDR-format encoders  **
  704.  **                       **
  705.  ***************************/
  706.  
  707. #ifdef FAKEXDRFLOAT
  708.  
  709. /*
  710. ** These two are missing on some machines.
  711. */
  712.  
  713. static int
  714. xdr_float(xdrp, fp)
  715.     XDR *xdrp;
  716.     float *fp;
  717. {
  718.     return xdr_long(xdrp, (long*)fp);
  719. }
  720.  
  721.  
  722. static int
  723. xdr_double(xdrp, dp)
  724.     XDR *xdrp;
  725.     double *dp;
  726. {
  727.     return xdr_long(xdrp, (long*)dp + 1) && xdr_long(xdrp, (long*)dp);
  728. }
  729.  
  730. #endif/*FAKEXDRFLOAT*/
  731.  
  732. #if    defined(BOGUSXDR)
  733.  
  734. /*
  735. ** Encoders for machines without XDR routines but with XDR-format
  736. ** data.
  737. */
  738.  
  739. static int
  740. enc_xdr_init(mp)
  741.     struct pmsg *mp;
  742. {
  743.     return enc_raw_init();
  744. }
  745.  
  746. static int
  747. enc_xdr_byte(mp, vp, cnt, std, siz)
  748.     struct pmsg *mp;
  749.     void *vp;
  750.     int cnt, std, siz;
  751. {
  752.     struct frag *fp;
  753.     int cc;
  754.  
  755.     fp = mp->m_frag->fr_rlink;
  756.     if (cc = bytepk(mp, (char*)vp, cnt, siz, std * siz))
  757.         return cc;
  758.     fp->fr_len = (fp->fr_len + 3) & ~3;
  759.     return 0;
  760. }
  761.  
  762. static int
  763. enc_xdr_short(mp, vp, cnt, std, siz)
  764.     struct pmsg *mp;
  765.     void *vp;
  766.     int cnt, std, siz;
  767. {
  768.     register short *np;
  769.     register char *cp;
  770.     char     buf[4];
  771.     int cc = 0;
  772.  
  773.     for (np = (short*)vp; cnt-- > 0; np += std) {
  774.         cp = (char *)np;
  775.         buf[3] = *cp;
  776.         buf[2] = *(cp+1);
  777.         if (cc = bytepk(mp, buf, 4, 1, 1))
  778.             return cc;
  779.     }
  780.     return 0;
  781. }
  782.  
  783. static int
  784. enc_xdr_int(mp, vp, cnt, std, siz)
  785.     struct pmsg *mp;
  786.     void *vp;
  787.     int cnt, std, siz;
  788. {
  789.     register int *np;
  790.     register char *cp;
  791.     char     buf[4];
  792.     int cc = 0;
  793.  
  794.     for (np = (int *)vp; cnt-- > 0; np += std) {
  795.         cp = (char *)np;
  796.         buf[3] = *cp;
  797.         buf[2] = *(cp+1);
  798.         buf[1] = *(cp+2);
  799.         buf[0] = *(cp+3);
  800.         if (cc = bytepk(mp, buf, 4, 1, 1))
  801.             return cc;
  802.     }
  803.     return 0;
  804. }
  805.  
  806. static int
  807. enc_xdr_long(mp, vp, cnt, std, siz)
  808.     struct pmsg *mp;
  809.     void *vp;
  810.     int cnt, std, siz;
  811. {
  812.     register long *np;
  813.     register char *cp;
  814.     char     buf[4];
  815.     int cc = 0;
  816.  
  817.     for (np = (long *)vp; cnt-- > 0; np += std) {
  818.         cp = (char *)np;
  819.         buf[3] = *cp;
  820.         buf[2] = *(cp+1);
  821.         buf[1] = *(cp+2);
  822.         buf[0] = *(cp+3);
  823.         if (cc = bytepk(mp, buf, 4, 1, 1))
  824.             return cc;
  825.     }
  826.     return 0;
  827. }
  828.  
  829. static int
  830. enc_xdr_float(mp, vp, cnt, std, siz)
  831.     struct pmsg *mp;
  832.     void *vp;
  833.     int cnt, std, siz;
  834. {
  835.     register float *np;
  836.     register char *cp;
  837.     char     buf[4];
  838.     int cc = 0;
  839.  
  840.     for (np = (float *)vp; cnt-- > 0; np += std) {
  841.         cp = (char *)np;
  842.         buf[3] = *cp;
  843.         buf[2] = *(cp+1);
  844.         buf[1] = *(cp+2);
  845.         buf[0] = *(cp+3);
  846.         if (cc = bytepk(mp, buf, 4, 1, 1))
  847.             return cc;
  848.     }
  849.     return 0;
  850. }
  851.  
  852. static int
  853. enc_xdr_double(mp, vp, cnt, std, siz)
  854.     struct pmsg *mp;
  855.     void *vp;
  856.     int cnt, std, siz;
  857. {
  858.     register double *np;
  859.     register char *cp;
  860.     char     buf[8];
  861.     int cc = 0;
  862.  
  863.     for (np = (double *)vp; cnt-- > 0; np += std) {
  864.         cp = (char *)np;
  865.         buf[7] = *cp;
  866.         buf[6] = *(cp+1);
  867.         buf[5] = *(cp+2);
  868.         buf[4] = *(cp+3);
  869.         buf[3] = *(cp+4);
  870.         buf[2] = *(cp+5);
  871.         buf[1] = *(cp+6);
  872.         buf[0] = *(cp+7);
  873.         if (cc = bytepk(mp, buf, 8, 1, 1))
  874.             return cc;
  875.     }
  876.     return 0;
  877. }
  878.  
  879. typedef struct {float r, i;} complex;
  880. typedef struct {double r, i;} dcplx;
  881.  
  882. static int
  883. enc_xdr_cplx(mp, vp, cnt, std, siz)
  884.     struct pmsg *mp;
  885.     void *vp;
  886.     int cnt, std, siz;
  887. {
  888.     register complex *np;
  889.     register char *cp;
  890.     char buf[8];
  891.     int cc = 0;
  892.  
  893.     for (np = (complex *)vp; cnt-- > 0; np += std) {
  894.         cp = (char *)np;
  895.         buf[3] = *cp;
  896.         buf[2] = *(cp+1);
  897.         buf[1] = *(cp+2);
  898.         buf[0] = *(cp+3);
  899.         buf[7] = *(cp+4);
  900.         buf[6] = *(cp+5);
  901.         buf[5] = *(cp+6);
  902.         buf[4] = *(cp+7);
  903.         if (cc = bytepk(mp, buf, 8, 1, 1))
  904.             return cc;
  905.     }
  906.     return 0;
  907. }
  908.  
  909. static int
  910. enc_xdr_dcplx(mp, vp, cnt, std, siz)
  911.     struct pmsg *mp;
  912.     void *vp;
  913.     int cnt, std, siz;
  914. {
  915.     register dcplx *np;
  916.     register char *cp;
  917.     char buf[16];
  918.     int cc = 0;
  919.  
  920.     for (np = (dcplx *)vp; cnt-- > 0; np += std) {
  921.         cp = (char *)np;
  922.         buf[7] = *cp;
  923.         buf[6] = *(cp+1);
  924.         buf[5] = *(cp+2);
  925.         buf[4] = *(cp+3);
  926.         buf[3] = *(cp+4);
  927.         buf[2] = *(cp+5);
  928.         buf[1] = *(cp+6);
  929.         buf[0] = *(cp+7);
  930.         buf[15] = *(cp+8);
  931.         buf[14] = *(cp+9);
  932.         buf[13] = *(cp+10);
  933.         buf[12] = *(cp+11);
  934.         buf[11] = *(cp+12);
  935.         buf[10] = *(cp+13);
  936.         buf[9] = *(cp+14);
  937.         buf[8] = *(cp+15);
  938.         if (cc = bytepk(mp, buf, 16, 1, 1))
  939.             return cc;
  940.     }
  941.     return 0;
  942. }
  943.  
  944. static int
  945. dec_xdr_init(mp)
  946.     struct pmsg *mp;
  947. {
  948.     return dec_raw_init();
  949. }
  950.  
  951. static int
  952. dec_xdr_byte(mp, vp, cnt, std, siz)
  953.     struct pmsg *mp;
  954.     void *vp;
  955.     int cnt, std, siz;
  956. {
  957.     int cc;
  958.  
  959.     if (cc = byteupk(mp, (char*)vp, cnt, siz, std * siz))
  960.         return cc;
  961.     mp->m_cpos = (mp->m_cpos + 3) & ~3;
  962.     return 0;
  963. }
  964.  
  965. static int
  966. dec_xdr_short(mp, vp, cnt, std, siz)
  967.     struct pmsg *mp;
  968.     void *vp;
  969.     int cnt, std, siz;
  970. {
  971.     register short *np;
  972.     register char *cp;
  973.     char     buf[4];
  974.     int cc = 0;
  975.  
  976.     for (np = (short*)vp; cnt-- > 0; np += std) {
  977.         if (cc = byteupk(mp, buf, 4, 1, 1))
  978.             return cc;
  979.         cp = (char *)np;
  980.         *cp = buf[3];
  981.         *(cp+1) = buf[2];
  982.     }
  983.     return 0;
  984. }
  985.  
  986. static int
  987. dec_xdr_int(mp, vp, cnt, std, siz)
  988.     struct pmsg *mp;
  989.     void *vp;
  990.     int cnt, std, siz;
  991. {
  992.     register int *np;
  993.     register char *cp;
  994.     char     buf[4];
  995.     int cc = 0;
  996.  
  997.     for (np = (int *)vp; cnt-- > 0; np += std) {
  998.         if (cc = byteupk(mp, buf, 4, 1, 1))
  999.             return cc;
  1000.         cp = (char *)np;
  1001.         *cp = buf[3];
  1002.         *(cp+1) = buf[2];
  1003.         *(cp+2) = buf[1];
  1004.         *(cp+3) = buf[0];
  1005.     }
  1006.     return 0;
  1007. }
  1008.  
  1009. static int
  1010. dec_xdr_long(mp, vp, cnt, std, siz)
  1011.     struct pmsg *mp;
  1012.     void *vp;
  1013.     int cnt, std, siz;
  1014. {
  1015.     register long *np;
  1016.     register char *cp;
  1017.     char     buf[4];
  1018.     int cc = 0;
  1019.  
  1020.     for (np = (long *)vp; cnt-- > 0; np += std) {
  1021.         if (cc = byteupk(mp, buf, 4, 1, 1))
  1022.             return cc;
  1023.         cp = (char *)np;
  1024.         *cp = buf[3];
  1025.         *(cp+1) = buf[2];
  1026.         *(cp+2) = buf[1];
  1027.         *(cp+3) = buf[0];
  1028.     }
  1029.     return 0;
  1030. }
  1031.  
  1032. static int
  1033. dec_xdr_float(mp, vp, cnt, std, siz)
  1034.     struct pmsg *mp;
  1035.     void *vp;
  1036.     int cnt, std, siz;
  1037. {
  1038.     register float *np;
  1039.     register char *cp;
  1040.     char     buf[4];
  1041.     int cc = 0;
  1042.  
  1043.     for (np = (float *)vp; cnt-- > 0; np += std) {
  1044.         if (cc = byteupk(mp, buf, 4, 1, 1))
  1045.             return cc;
  1046.         cp = (char *)np;
  1047.         *cp = buf[3];
  1048.         *(cp+1) = buf[2];
  1049.         *(cp+2) = buf[1];
  1050.         *(cp+3) = buf[0];
  1051.     }
  1052.     return 0;
  1053. }
  1054.  
  1055. static int
  1056. dec_xdr_double(mp, vp, cnt, std, siz)
  1057.     struct pmsg *mp;
  1058.     void *vp;
  1059.     int cnt, std, siz;
  1060. {
  1061.     register double *np;
  1062.     register char *cp;
  1063.     char     buf[8];
  1064.     int cc = 0;
  1065.  
  1066.     for (np = (double *)vp; cnt-- > 0; np += std) {
  1067.         if (cc = byteupk(mp, buf, 8, 1, 1))
  1068.             return cc;
  1069.         cp = (char *)np;
  1070.         *cp = buf[7];
  1071.         *(cp+1) = buf[6];
  1072.         *(cp+2) = buf[5];
  1073.         *(cp+3) = buf[4];
  1074.         *(cp+4) = buf[3];
  1075.         *(cp+5) = buf[2];
  1076.         *(cp+6) = buf[1];
  1077.         *(cp+7) = buf[0];
  1078.     }
  1079.     return 0;
  1080. }
  1081.  
  1082. static int
  1083. dec_xdr_cplx(mp, vp, cnt, std, siz)
  1084.     struct pmsg *mp;
  1085.     void *vp;
  1086.     int cnt, std, siz;
  1087. {
  1088.     register complex *np;
  1089.     register char *cp;
  1090.     char     buf[8];
  1091.     int cc = 0;
  1092.  
  1093.     for (np = (complex *)vp; cnt-- > 0; np += std) {
  1094.         if (cc = byteupk(mp, buf, 8, 1, 1))
  1095.             return cc;
  1096.         cp = (char *)np;
  1097.         *cp = buf[3];
  1098.         *(cp+1) = buf[2];
  1099.         *(cp+2) = buf[1];
  1100.         *(cp+3) = buf[0];
  1101.         *(cp+4) = buf[7];
  1102.         *(cp+5) = buf[6];
  1103.         *(cp+6) = buf[5];
  1104.         *(cp+7) = buf[4];
  1105.     }
  1106.     return 0;
  1107. }
  1108.  
  1109. static int
  1110. dec_xdr_dcplx(mp, vp, cnt, std, siz)
  1111.     struct pmsg *mp;
  1112.     void *vp;
  1113.     int cnt, std, siz;
  1114. {
  1115.     register dcplx *np;
  1116.     register char *cp;
  1117.     char     buf[16];
  1118.     int cc = 0;
  1119.  
  1120.     for (np = (dcplx *)vp; cnt-- > 0; np += std) {
  1121.         if (cc = byteupk(mp, buf, 16, 1, 1))
  1122.             return cc;
  1123.         cp = (char *)np;
  1124.         *cp     = buf[7];
  1125.         *(cp+1) = buf[6];
  1126.         *(cp+2) = buf[5];
  1127.         *(cp+3) = buf[4];
  1128.         *(cp+4) = buf[3];
  1129.         *(cp+5) = buf[2];
  1130.         *(cp+6) = buf[1];
  1131.         *(cp+7) = buf[0];
  1132.         *(cp+8) = buf[15];
  1133.         *(cp+9) = buf[14];
  1134.         *(cp+10) = buf[13];
  1135.         *(cp+11) = buf[12];
  1136.         *(cp+12) = buf[11];
  1137.         *(cp+13) = buf[10];
  1138.         *(cp+14) = buf[9];
  1139.         *(cp+15) = buf[8];
  1140.     }
  1141.     return 0;
  1142. }
  1143.  
  1144. #else    /*BOGUSXDR*/
  1145.  
  1146. /*
  1147. ** These are the normal XDR encoders for machines with XDR functions.
  1148. */
  1149.  
  1150. /*    enc_xdr_init()
  1151. *
  1152. *    Initialize a message buffer to pack XDR format data
  1153. */
  1154.  
  1155. static int
  1156. enc_xdr_init(mp)
  1157.     struct pmsg *mp;
  1158. {
  1159.     struct frag *fp;
  1160.     int cc;
  1161.  
  1162.     if (!(mp->m_flag & MM_PACK)) {
  1163.         mp->m_flag &= ~MM_UPACK;
  1164.         mp->m_flag |= MM_PACK;
  1165.         if ((fp = mp->m_frag->fr_link) == mp->m_frag) {
  1166.             if (cc = pmsg_extend(mp))
  1167.                 return cc;
  1168.             fp = fp->fr_link;
  1169.         }
  1170.  
  1171.         xdrmem_create(&mp->m_xdr,
  1172.                 fp->fr_dat,
  1173.                 (unsigned)(fp->fr_max - (fp->fr_dat - fp->fr_buf)),
  1174.                 XDR_ENCODE);
  1175.     }
  1176.     return 0;
  1177. }
  1178.  
  1179.  
  1180. /*    enc_xdr_step()
  1181. *
  1182. *    Add a new fragment to an XDR format message
  1183. */
  1184.  
  1185. static int
  1186. enc_xdr_step(mp)
  1187.     struct pmsg *mp;
  1188. {
  1189.     struct frag *fp;
  1190.     int cc;
  1191.  
  1192.     if (cc = pmsg_extend(mp))
  1193.         return cc;
  1194.     fp = mp->m_frag->fr_rlink;
  1195.     xdrmem_create(&mp->m_xdr,
  1196.             fp->fr_dat,
  1197.             (unsigned)(fp->fr_max - (fp->fr_dat - fp->fr_buf)),
  1198.             XDR_ENCODE);
  1199.     return 0;
  1200. }
  1201.  
  1202.  
  1203. static int
  1204. enc_xdr_byte(mp, vp, cnt, std, siz)
  1205.     struct pmsg *mp;
  1206.     void *vp;
  1207.     int cnt, std, siz;
  1208. {
  1209.     struct frag *fp;
  1210.     int cc;
  1211.  
  1212.     fp = mp->m_frag->fr_rlink;
  1213.     if (cc = bytepk(mp, (char*)vp, cnt, 1, std))
  1214.         return cc;
  1215.     if (fp != mp->m_frag->fr_rlink) {
  1216.         fp = mp->m_frag->fr_rlink;
  1217.         xdrmem_create(&mp->m_xdr,
  1218.                 fp->fr_dat,
  1219.                 (unsigned)(fp->fr_max - (fp->fr_dat - fp->fr_buf)),
  1220.                 XDR_ENCODE);
  1221.     }
  1222.     fp->fr_len = (fp->fr_len + 3) & ~3;
  1223.     xdr_setpos(&mp->m_xdr, fp->fr_len);
  1224.     return 0;
  1225. }
  1226.  
  1227.  
  1228. static int
  1229. enc_xdr_short(mp, vp, cnt, std, siz)
  1230.     struct pmsg *mp;
  1231.     void *vp;
  1232.     int cnt, std, siz;
  1233. {
  1234.     register short *np;
  1235.     int cc = 0;
  1236.  
  1237.     for (np = (short*)vp; cnt-- > 0; np += std)
  1238.         if (!xdr_short(&mp->m_xdr, np)) {
  1239.             mp->m_frag->fr_rlink->fr_len = xdr_getpos(&mp->m_xdr);
  1240.             if (cc = enc_xdr_step(mp))
  1241.                 break;
  1242.             else
  1243.                 if (!xdr_short(&mp->m_xdr, np)) {
  1244.                     cc = PvmNoMem;
  1245.                     break;
  1246.                 }
  1247.         }
  1248.     mp->m_frag->fr_rlink->fr_len = xdr_getpos(&mp->m_xdr);
  1249.     return cc;
  1250. }
  1251.  
  1252.  
  1253. static int
  1254. enc_xdr_int(mp, vp, cnt, std, siz)
  1255.     struct pmsg *mp;
  1256.     void *vp;
  1257.     int cnt, std, siz;
  1258. {
  1259.     register int *np;
  1260.     int cc = 0;
  1261.  
  1262.     for (np = (int*)vp; cnt-- > 0; np += std)
  1263.         if (!xdr_int(&mp->m_xdr, np)) {
  1264.             mp->m_frag->fr_rlink->fr_len = xdr_getpos(&mp->m_xdr);
  1265.             if (cc = enc_xdr_step(mp))
  1266.                 break;
  1267.             else
  1268.                 if (!xdr_int(&mp->m_xdr, np)) {
  1269.                     cc = PvmNoMem;
  1270.                     break;
  1271.                 }
  1272.         }
  1273.     mp->m_frag->fr_rlink->fr_len = xdr_getpos(&mp->m_xdr);
  1274.     return cc;
  1275. }
  1276.  
  1277.  
  1278. static int
  1279. enc_xdr_long(mp, vp, cnt, std, siz)
  1280.     struct pmsg *mp;
  1281.     void *vp;
  1282.     int cnt, std, siz;
  1283. {
  1284.     register long *np;
  1285.     int cc = 0;
  1286.  
  1287.     for (np = (long*)vp; cnt-- > 0; np += std)
  1288.         if (!xdr_long(&mp->m_xdr, np)) {
  1289.             if ((*np & ~(long)0x7fffffff)
  1290.             && (*np & ~(long)0x7fffffff) != ~(long)0x7fffffff) {
  1291.                 cc = PvmOverflow;
  1292.                 break;
  1293.             }
  1294.             mp->m_frag->fr_rlink->fr_len = xdr_getpos(&mp->m_xdr);
  1295.             if (cc = enc_xdr_step(mp))
  1296.                 break;
  1297.             else
  1298.                 if (!xdr_long(&mp->m_xdr, np)) {
  1299.                     cc = PvmNoMem;
  1300.                     break;
  1301.                 }
  1302.         }
  1303.     mp->m_frag->fr_rlink->fr_len = xdr_getpos(&mp->m_xdr);
  1304.     return cc;
  1305. }
  1306.  
  1307.  
  1308. static int
  1309. enc_xdr_ulong(mp, vp, cnt, std, siz)
  1310.     struct pmsg *mp;
  1311.     void *vp;
  1312.     int cnt, std, siz;
  1313. {
  1314.     register unsigned long *np;
  1315.     int cc = 0;
  1316.  
  1317.     for (np = (unsigned long*)vp; cnt-- > 0; np += std)
  1318.         if (!xdr_u_long(&mp->m_xdr, np)) {
  1319.             if (*np & ~(long)0xffffffff) {
  1320.                 cc = PvmOverflow;
  1321.                 break;
  1322.             }
  1323.             mp->m_frag->fr_rlink->fr_len = xdr_getpos(&mp->m_xdr);
  1324.             if (cc = enc_xdr_step(mp))
  1325.                 break;
  1326.             else
  1327.                 if (!xdr_u_long(&mp->m_xdr, np)) {
  1328.                     cc = PvmNoMem;
  1329.                     break;
  1330.                 }
  1331.         }
  1332.     mp->m_frag->fr_rlink->fr_len = xdr_getpos(&mp->m_xdr);
  1333.     return cc;
  1334. }
  1335.  
  1336.  
  1337. static int
  1338. enc_xdr_float(mp, vp, cnt, std, siz)
  1339.     struct pmsg *mp;
  1340.     void *vp;
  1341.     int cnt, std, siz;
  1342. {
  1343.     register float *fp;
  1344.     int cc = 0;
  1345.  
  1346.     for (fp = (float*)vp; cnt-- > 0; fp += std)
  1347.         if (!xdr_float(&mp->m_xdr, fp)) {
  1348.             mp->m_frag->fr_rlink->fr_len = xdr_getpos(&mp->m_xdr);
  1349.             if (cc = enc_xdr_step(mp))
  1350.                 break;
  1351.             else
  1352.                 if (!xdr_float(&mp->m_xdr, fp)) {
  1353.                     cc = PvmNoMem;
  1354.                     break;
  1355.                 }
  1356.         }
  1357.     mp->m_frag->fr_rlink->fr_len = xdr_getpos(&mp->m_xdr);
  1358.     return cc;
  1359. }
  1360.  
  1361.  
  1362. static int
  1363. enc_xdr_double(mp, vp, cnt, std, siz)
  1364.     struct pmsg *mp;
  1365.     void *vp;
  1366.     int cnt, std, siz;
  1367. {
  1368.     register double *dp;
  1369.     int cc = 0;
  1370.     int n;
  1371.  
  1372.     for (dp = (double*)vp; cnt-- > 0; dp += std) {
  1373.         if (!xdr_double(&mp->m_xdr, dp)) {
  1374.             if (cc = enc_xdr_step(mp))
  1375.                 break;
  1376.             else
  1377.                 if (!xdr_double(&mp->m_xdr, dp)) {
  1378.                     cc = PvmNoMem;
  1379.                     break;
  1380.                 }
  1381.         }
  1382.         mp->m_frag->fr_rlink->fr_len = xdr_getpos(&mp->m_xdr);
  1383.     }
  1384.     return cc;
  1385. }
  1386.  
  1387.  
  1388. static int
  1389. enc_xdr_cplx(mp, vp, cnt, std, siz)
  1390.     struct pmsg *mp;
  1391.     void *vp;
  1392.     int cnt, std, siz;
  1393. {
  1394.     register float *xp;
  1395.     int cc = 0;
  1396.  
  1397.     std = std * 2 - 1;
  1398.     for (xp = (float*)vp; cnt-- > 0; xp += std) {
  1399.         if (!xdr_float(&mp->m_xdr, xp)) {
  1400.             mp->m_frag->fr_rlink->fr_len = xdr_getpos(&mp->m_xdr);
  1401.             if (cc = enc_xdr_step(mp))
  1402.                 break;
  1403.             else
  1404.                 if (!xdr_float(&mp->m_xdr, xp)) {
  1405.                     cc = PvmNoMem;
  1406.                     break;
  1407.                 }
  1408.         }
  1409.         xp++;
  1410.         if (!xdr_float(&mp->m_xdr, xp)) {
  1411.             mp->m_frag->fr_rlink->fr_len = xdr_getpos(&mp->m_xdr);
  1412.             if (cc = enc_xdr_step(mp))
  1413.                 break;
  1414.             else
  1415.                 if (!xdr_float(&mp->m_xdr, xp)) {
  1416.                     cc = PvmNoMem;
  1417.                     break;
  1418.                 }
  1419.         }
  1420.     }
  1421.     mp->m_frag->fr_rlink->fr_len = xdr_getpos(&mp->m_xdr);
  1422.     return cc;
  1423. }
  1424.  
  1425.  
  1426. static int
  1427. enc_xdr_dcplx(mp, vp, cnt, std, siz)
  1428.     struct pmsg *mp;
  1429.     void *vp;
  1430.     int cnt, std, siz;
  1431. {
  1432.     register double *zp;
  1433.     int cc = 0;
  1434.  
  1435.     std = std * 2 - 1;
  1436.     for (zp = (double*)vp; cnt-- > 0; zp += std) {
  1437.         if (!xdr_double(&mp->m_xdr, zp)) {
  1438.             if (cc = enc_xdr_step(mp))
  1439.                 break;
  1440.             else
  1441.                 if (!xdr_double(&mp->m_xdr, zp)) {
  1442.                     cc = PvmNoMem;
  1443.                     break;
  1444.                 }
  1445.         }
  1446.         mp->m_frag->fr_rlink->fr_len = xdr_getpos(&mp->m_xdr);
  1447.         zp++;
  1448.         if (!xdr_double(&mp->m_xdr, zp)) {
  1449.             if (cc = enc_xdr_step(mp))
  1450.                 break;
  1451.             else
  1452.                 if (!xdr_double(&mp->m_xdr, zp)) {
  1453.                     cc = PvmNoMem;
  1454.                     break;
  1455.                 }
  1456.         }
  1457.         mp->m_frag->fr_rlink->fr_len = xdr_getpos(&mp->m_xdr);
  1458.     }
  1459.     return cc;
  1460. }
  1461.  
  1462.  
  1463. /*    dec_xdr_init()
  1464. *
  1465. *    Initialize a message buffer to unpack XDR format data.
  1466. */
  1467.  
  1468. static int
  1469. dec_xdr_init(mp)
  1470.     struct pmsg *mp;
  1471. {
  1472.     struct frag *fp = mp->m_frag->fr_link;
  1473.  
  1474.     if (!(mp->m_flag & MM_UPACK)) {
  1475.         mp->m_flag &= ~MM_PACK;
  1476.         mp->m_flag |= MM_UPACK;
  1477.         mp->m_cfrag = fp;
  1478.         mp->m_cpos = 0;
  1479.         xdrmem_create(&mp->m_xdr, fp->fr_dat, (unsigned)(fp->fr_len),
  1480.                 XDR_DECODE);
  1481.     }
  1482.     return 0;
  1483. }
  1484.  
  1485.  
  1486. /*    dec_xdr_step()
  1487. *
  1488. *    Step to the next fragment of an XDR format message.
  1489. *
  1490. *    The current fragment might not be fully consumed - messages are
  1491. *    refragmented on 4-byte boundaries, but XDR 'atomic' sizes for
  1492. *    us are 4 bytes and 8 bytes (doubles).
  1493. *    If the next fragment exists, copy the remaining bytes to the head
  1494. *    of its buffer and continue unpacking.
  1495. *    XXX 1. There might not be enough headroom (unlikely).
  1496. *    XXX 2. If we share databufs we can't modify them (maybe?).
  1497. */
  1498.  
  1499. static int
  1500. dec_xdr_step(mp)
  1501.     struct pmsg *mp;
  1502. {
  1503.     struct frag *fp;
  1504.     int cc;
  1505.     int l;
  1506.     char *p;
  1507.  
  1508.     if (mp->m_cpos != mp->m_cfrag->fr_len) {
  1509.         p = mp->m_cfrag->fr_dat + mp->m_cpos;
  1510.         l = mp->m_cfrag->fr_len - mp->m_cpos;
  1511.  
  1512.         if (cc = pmsg_decmore(mp))
  1513.             return cc;
  1514.  
  1515.         fp = mp->m_cfrag;
  1516.         if (fp->fr_dat - fp->fr_buf < l) {
  1517.             pvmlogerror("aaugh, no space for fixup, kill me\n");
  1518.             return PvmBadMsg;
  1519.  
  1520.         } else {
  1521. /*
  1522.             pvmlogprintf("fragment has %d bytes left, doing fixup\n", l);
  1523. */
  1524.             fp->fr_dat -= l;
  1525.             fp->fr_len += l;
  1526.             BCOPY(p, fp->fr_dat, l);
  1527.         }
  1528.  
  1529.     } else {
  1530.         if (cc = pmsg_decmore(mp))
  1531.             return cc;
  1532.         fp = mp->m_cfrag;
  1533.     }
  1534.     xdrmem_create(&mp->m_xdr, fp->fr_dat, (unsigned)(fp->fr_len),
  1535.             XDR_DECODE);
  1536.     return 0;
  1537. }
  1538.  
  1539.  
  1540. static int
  1541. dec_xdr_byte(mp, vp, cnt, std, siz)
  1542.     struct pmsg *mp;
  1543.     void *vp;
  1544.     int cnt, std, siz;
  1545. {
  1546.     struct frag *fp;
  1547.     int cc;
  1548.  
  1549.     fp = mp->m_cfrag;
  1550.     if (cc = byteupk(mp, (char*)vp, cnt, 1, std))
  1551.         return cc;
  1552.     if (fp != mp->m_cfrag) {
  1553.         fp = mp->m_cfrag;
  1554.         xdrmem_create(&mp->m_xdr, fp->fr_dat, (unsigned)(fp->fr_len),
  1555.                 XDR_DECODE);
  1556.     }
  1557.     mp->m_cpos = (mp->m_cpos + 3) & ~3;
  1558.     xdr_setpos(&mp->m_xdr, mp->m_cpos);
  1559.     return 0;
  1560. }
  1561.  
  1562.  
  1563. static int
  1564. dec_xdr_short(mp, vp, cnt, std, siz)
  1565.     struct pmsg *mp;
  1566.     void *vp;
  1567.     int cnt, std, siz;
  1568. {
  1569.     register short *np;
  1570.     int cc = 0;
  1571.  
  1572.     for (np = (short*)vp; cnt-- > 0; np += std)
  1573.         if (!xdr_short(&mp->m_xdr, np)) {
  1574.             mp->m_cpos = xdr_getpos(&mp->m_xdr);
  1575.             if (cc = dec_xdr_step(mp))
  1576.                 break;
  1577.             else
  1578.                 if (!xdr_short(&mp->m_xdr, np)) {
  1579.                     cc = PvmNoData;
  1580.                     break;
  1581.                 }
  1582.         }
  1583.     mp->m_cpos = xdr_getpos(&mp->m_xdr);
  1584.     return cc;
  1585. }
  1586.  
  1587.  
  1588. static int
  1589. dec_xdr_int(mp, vp, cnt, std, siz)
  1590.     struct pmsg *mp;
  1591.     void *vp;
  1592.     int cnt, std, siz;
  1593. {
  1594.     register int *np;
  1595.     int cc = 0;
  1596.  
  1597.     for (np = (int*)vp; cnt-- > 0; np += std)
  1598.         if (!xdr_int(&mp->m_xdr, np)) {
  1599.             mp->m_cpos = xdr_getpos(&mp->m_xdr);
  1600.             if (cc = dec_xdr_step(mp))
  1601.                 break;
  1602.             else
  1603.                 if (!xdr_int(&mp->m_xdr, np)) {
  1604.                     cc = PvmNoData;
  1605.                     break;
  1606.                 }
  1607.         }
  1608.     mp->m_cpos = xdr_getpos(&mp->m_xdr);
  1609.     return cc;
  1610. }
  1611.  
  1612.  
  1613. static int
  1614. dec_xdr_long(mp, vp, cnt, std, siz)
  1615.     struct pmsg *mp;
  1616.     void *vp;
  1617.     int cnt, std, siz;
  1618. {
  1619.     register long *np;
  1620.     int cc = 0;
  1621.  
  1622.     for (np = (long*)vp; cnt-- > 0; np += std)
  1623.         if (!xdr_long(&mp->m_xdr, np)) {
  1624.             mp->m_cpos = xdr_getpos(&mp->m_xdr);
  1625.             if (cc = dec_xdr_step(mp))
  1626.                 break;
  1627.             else
  1628.                 if (!xdr_long(&mp->m_xdr, np)) {
  1629.                     cc = PvmNoData;
  1630.                     break;
  1631.                 }
  1632.         }
  1633.     mp->m_cpos = xdr_getpos(&mp->m_xdr);
  1634.     return cc;
  1635. }
  1636.  
  1637.  
  1638. static int
  1639. dec_xdr_ushort(mp, vp, cnt, std, siz)
  1640.     struct pmsg *mp;
  1641.     void *vp;
  1642.     int cnt, std, siz;
  1643. {
  1644.     register unsigned short *np;
  1645.     int cc = 0;
  1646.  
  1647.     for (np = (unsigned short*)vp; cnt-- > 0; np += std)
  1648.         if (!xdr_u_short(&mp->m_xdr, np)) {
  1649.             mp->m_cpos = xdr_getpos(&mp->m_xdr);
  1650.             if (cc = dec_xdr_step(mp))
  1651.                 break;
  1652.             else
  1653.                 if (!xdr_u_short(&mp->m_xdr, np)) {
  1654.                     cc = PvmNoData;
  1655.                     break;
  1656.                 }
  1657.         }
  1658.     mp->m_cpos = xdr_getpos(&mp->m_xdr);
  1659.     return cc;
  1660. }
  1661.  
  1662.  
  1663. static int
  1664. dec_xdr_uint(mp, vp, cnt, std, siz)
  1665.     struct pmsg *mp;
  1666.     void *vp;
  1667.     int cnt, std, siz;
  1668. {
  1669.     register unsigned int *np;
  1670.     int cc = 0;
  1671.  
  1672.     for (np = (unsigned int*)vp; cnt-- > 0; np += std)
  1673.         if (!xdr_u_int(&mp->m_xdr, np)) {
  1674.             mp->m_cpos = xdr_getpos(&mp->m_xdr);
  1675.             if (cc = dec_xdr_step(mp))
  1676.                 break;
  1677.             else
  1678.                 if (!xdr_u_int(&mp->m_xdr, np)) {
  1679.                     cc = PvmNoData;
  1680.                     break;
  1681.                 }
  1682.         }
  1683.     mp->m_cpos = xdr_getpos(&mp->m_xdr);
  1684.     return cc;
  1685. }
  1686.  
  1687.  
  1688. static int
  1689. dec_xdr_ulong(mp, vp, cnt, std, siz)
  1690.     struct pmsg *mp;
  1691.     void *vp;
  1692.     int cnt, std, siz;
  1693. {
  1694.     register unsigned long *np;
  1695.     int cc = 0;
  1696.  
  1697.     for (np = (unsigned long*)vp; cnt-- > 0; np += std)
  1698.         if (!xdr_u_long(&mp->m_xdr, np)) {
  1699.             mp->m_cpos = xdr_getpos(&mp->m_xdr);
  1700.             if (cc = dec_xdr_step(mp))
  1701.                 break;
  1702.             else
  1703.                 if (!xdr_u_long(&mp->m_xdr, np)) {
  1704.                     cc = PvmNoData;
  1705.                     break;
  1706.                 }
  1707.         }
  1708.     mp->m_cpos = xdr_getpos(&mp->m_xdr);
  1709.     return cc;
  1710. }
  1711.  
  1712.  
  1713. static int
  1714. dec_xdr_float(mp, vp, cnt, std, siz)
  1715.     struct pmsg *mp;
  1716.     void *vp;
  1717.     int cnt, std, siz;
  1718. {
  1719.     register float *fp;
  1720.     int cc = 0;
  1721.  
  1722.     for (fp = (float*)vp; cnt-- > 0; fp += std)
  1723.         if (!xdr_float(&mp->m_xdr, fp)) {
  1724.             mp->m_cpos = xdr_getpos(&mp->m_xdr);
  1725.             if (cc = dec_xdr_step(mp))
  1726.                 break;
  1727.             else
  1728.                 if (!xdr_float(&mp->m_xdr, fp)) {
  1729.                     cc = PvmNoData;
  1730.                     break;
  1731.                 }
  1732.         }
  1733.     mp->m_cpos = xdr_getpos(&mp->m_xdr);
  1734.     return cc;
  1735. }
  1736.  
  1737.  
  1738. static int
  1739. dec_xdr_double(mp, vp, cnt, std, siz)
  1740.     struct pmsg *mp;
  1741.     void *vp;
  1742.     int cnt, std, siz;
  1743. {
  1744.     register double *dp;
  1745.     int cc = 0;
  1746.  
  1747.     for (dp = (double*)vp; cnt-- > 0; dp += std) {
  1748.         if (!xdr_double(&mp->m_xdr, dp)) {
  1749.             if (cc = dec_xdr_step(mp))
  1750.                 break;
  1751.             else
  1752.                 if (!xdr_double(&mp->m_xdr, dp)) {
  1753.                     cc = PvmNoData;
  1754.                     break;
  1755.                 }
  1756.         }
  1757.         mp->m_cpos = xdr_getpos(&mp->m_xdr);
  1758.     }
  1759.     return cc;
  1760. }
  1761.  
  1762.  
  1763. static int
  1764. dec_xdr_cplx(mp, vp, cnt, std, siz)
  1765.     struct pmsg *mp;
  1766.     void *vp;
  1767.     int cnt, std, siz;
  1768. {
  1769.     register float *xp;
  1770.     int cc = 0;
  1771.  
  1772.     std = std * 2 - 1;
  1773.     for (xp = (float*)vp; cnt-- > 0; xp += std) {
  1774.         if (!xdr_float(&mp->m_xdr, xp)) {
  1775.             mp->m_cpos = xdr_getpos(&mp->m_xdr);
  1776.             if (cc = dec_xdr_step(mp))
  1777.                 break;
  1778.             else
  1779.                 if (!xdr_float(&mp->m_xdr, xp)) {
  1780.                     cc = PvmNoData;
  1781.                     break;
  1782.                 }
  1783.         }
  1784.         xp++;
  1785.         if (!xdr_float(&mp->m_xdr, xp)) {
  1786.             mp->m_cpos = xdr_getpos(&mp->m_xdr);
  1787.             if (cc = dec_xdr_step(mp))
  1788.                 break;
  1789.             else
  1790.                 if (!xdr_float(&mp->m_xdr, xp)) {
  1791.                     cc = PvmNoData;
  1792.                     break;
  1793.                 }
  1794.         }
  1795.     }
  1796.     mp->m_cpos = xdr_getpos(&mp->m_xdr);
  1797.     return cc;
  1798. }
  1799.  
  1800.  
  1801. static int
  1802. dec_xdr_dcplx(mp, vp, cnt, std, siz)
  1803.     struct pmsg *mp;
  1804.     void *vp;
  1805.     int cnt, std, siz;
  1806. {
  1807.     register double *zp;
  1808.     int cc = 0;
  1809.  
  1810.     std = std * 2 - 1;
  1811.     for (zp = (double*)vp; cnt-- > 0; zp += std) {
  1812.         if (!xdr_double(&mp->m_xdr, zp)) {
  1813.             if (cc = dec_xdr_step(mp))
  1814.                 break;
  1815.             else
  1816.                 if (!xdr_double(&mp->m_xdr, zp)) {
  1817.                     cc = PvmNoData;
  1818.                     break;
  1819.                 }
  1820.         }
  1821.         mp->m_cpos = xdr_getpos(&mp->m_xdr);
  1822.         zp++;
  1823.         if (!xdr_double(&mp->m_xdr, zp)) {
  1824.             if (cc = dec_xdr_step(mp))
  1825.                 break;
  1826.             else
  1827.                 if (!xdr_double(&mp->m_xdr, zp)) {
  1828.                     cc = PvmNoData;
  1829.                     break;
  1830.                 }
  1831.         }
  1832.         mp->m_cpos = xdr_getpos(&mp->m_xdr);
  1833.     }
  1834.     return cc;
  1835. }
  1836.  
  1837. #endif    /*BOGUSXDR*/
  1838.  
  1839. /*************************
  1840.  **  In-place encoders  **
  1841.  **                     **
  1842.  *************************/
  1843.  
  1844. static int
  1845. enc_inp_init(mp)
  1846.     struct pmsg *mp;
  1847. {
  1848.     return 0;
  1849. }
  1850.  
  1851.  
  1852. static int
  1853. enc_inp_any(mp, vp, cnt, std, siz)
  1854.     struct pmsg *mp;
  1855.     void *vp;
  1856.     int cnt, std, siz;
  1857. {
  1858.     struct frag *fp;
  1859.  
  1860.     if (std != 1)
  1861.         return PvmNotImpl;
  1862.     if (vp && cnt && siz) {
  1863.         fp = fr_snew((char *)vp, cnt * siz);
  1864.         LISTPUTBEFORE(mp->m_frag, fp, fr_link, fr_rlink);
  1865.     }
  1866. #if 0
  1867.     if (std != 1) {
  1868.         if (std < 1)
  1869.             return PvmBadParam;
  1870.         fp->fr_max = fp->fr_len = siz + (cnt - 1) * std * siz;
  1871.         fp->fr_csz = siz;
  1872.         fp->fr_lnc = std * siz;
  1873.         fp->fr_u.spr = 1;
  1874.     }
  1875. #endif
  1876.     return 0;
  1877. }
  1878.  
  1879.  
  1880. /*********************
  1881.  **  Trace encoders **
  1882.  **                 **
  1883.  *********************/
  1884.  
  1885. static int
  1886. enc_trc_init(mp)
  1887.     struct pmsg *mp;
  1888. {
  1889.     struct timeval timestamp;
  1890.  
  1891.     int tmp;
  1892.     int cc;
  1893.  
  1894.     gettimeofday( ×tamp, (struct timezone *) 0 );
  1895.  
  1896.     if ( (cc = enc_xdr_init(mp)) )
  1897.         return( cc );
  1898.  
  1899.     tmp = TEV_MARK_USER_EVENT_RECORD;
  1900.     if ((cc = enc_xdr_int(mp, (void *) &tmp, 1, 1, (int) sizeof(int))))
  1901.         return( cc );
  1902.  
  1903.     tmp = TEV_USER_DEFINED;
  1904.     if ((cc = enc_xdr_int(mp, (void *) &tmp, 1, 1, (int) sizeof(int))))
  1905.         return( cc );
  1906.  
  1907.     tmp = strlen( pvmtevinfo[TEV_USER_DEFINED].name ) + 1;
  1908.     if ((cc = enc_xdr_int(mp, (void *) &tmp, 1, 1, (int) sizeof(int))))
  1909.         return( cc );
  1910.  
  1911.     if ((cc = enc_xdr_byte(mp,
  1912.             (void *)(pvmtevinfo[TEV_USER_DEFINED].name), tmp, 1, 1)))
  1913.         return( cc );
  1914.  
  1915.     if ((cc = enc_xdr_int(mp, (void *) &(timestamp.tv_sec), 1, 1,
  1916.             (int) sizeof(int))))
  1917.         return( cc );
  1918.     if ((cc = enc_xdr_int(mp, (void *) &(timestamp.tv_usec), 1, 1,
  1919.             (int) sizeof(int))))
  1920.         return( cc );
  1921.  
  1922.     return( 0 );
  1923. }
  1924.  
  1925. int /* not static */
  1926. enc_trc_fin(mp)
  1927.     struct pmsg *mp;
  1928. {
  1929.     int tmp;
  1930.  
  1931.     tmp = TEV_MARK_USER_EVENT_RECORD_END;
  1932.     return( enc_xdr_int(mp, (void *) &tmp, 1, 1, (int) sizeof(int)) );
  1933. }
  1934.  
  1935. static int
  1936. enc_trc_byte(mp, vp, cnt, std, siz)
  1937.     struct pmsg *mp;
  1938.     void *vp;
  1939.     int cnt, std, siz;
  1940. {
  1941.     int type;
  1942.     int cc;
  1943.  
  1944.     if ( cnt )
  1945.     {
  1946.         if ( cnt == 1 ) {
  1947.             type = TEV_DATA_BYTE | TEV_DATA_SCALAR;
  1948.             if ( (cc = enc_xdr_int(mp, (void *) &type, 1, 1,
  1949.                     (int) sizeof(int))) )
  1950.                 return cc;
  1951.         }
  1952.         else {
  1953.             type = TEV_DATA_BYTE | TEV_DATA_ARRAY;
  1954.             if ( (cc = enc_xdr_int(mp, (void *) &type, 1, 1,
  1955.                     (int) sizeof(int))) )
  1956.                 return cc;
  1957.             if ( (cc = enc_xdr_int(mp, (void *) &cnt, 1, 1,
  1958.                     (int) sizeof(int))) )
  1959.                 return cc;
  1960.         }
  1961.         return enc_xdr_byte(mp, vp, cnt, std, siz);
  1962.     }
  1963.     return 0;
  1964. }
  1965.  
  1966. static int
  1967. enc_trc_short(mp, vp, cnt, std, siz)
  1968.     struct pmsg *mp;
  1969.     void *vp;
  1970.     int cnt, std, siz;
  1971. {
  1972.     int type;
  1973.     int cc;
  1974.  
  1975.     if ( cnt )
  1976.     {
  1977.         if ( cnt == 1 ) {
  1978.             type = TEV_DATA_SHORT | TEV_DATA_SCALAR;
  1979.             if ( (cc = enc_xdr_int(mp, (void *) &type, 1, 1,
  1980.                     (int) sizeof(int))) )
  1981.                 return cc;
  1982.         }
  1983.         else {
  1984.             type = TEV_DATA_SHORT | TEV_DATA_ARRAY;
  1985.             if ( (cc = enc_xdr_int(mp, (void *) &type, 1, 1,
  1986.                     (int) sizeof(int))) )
  1987.                 return cc;
  1988.             if ( (cc = enc_xdr_int(mp, (void *) &cnt, 1, 1,
  1989.                     (int) sizeof(int))) )
  1990.                 return cc;
  1991.         }
  1992.         return enc_xdr_short(mp, vp, cnt, std, siz);
  1993.     }
  1994.     return 0;
  1995. }
  1996.  
  1997. static int
  1998. enc_trc_int(mp, vp, cnt, std, siz)
  1999.     struct pmsg *mp;
  2000.     void *vp;
  2001.     int cnt, std, siz;
  2002. {
  2003.     int type;
  2004.     int cc;
  2005.  
  2006.     if ( cnt )
  2007.     {
  2008.         if ( cnt == 1 ) {
  2009.             type = TEV_DATA_INT | TEV_DATA_SCALAR;
  2010.             if ( (cc = enc_xdr_int(mp, (void *) &type, 1, 1,
  2011.                     (int) sizeof(int))) )
  2012.                 return cc;
  2013.         }
  2014.         else {
  2015.             type = TEV_DATA_INT | TEV_DATA_ARRAY;
  2016.             if ( (cc = enc_xdr_int(mp, (void *) &type, 1, 1,
  2017.                     (int) sizeof(int))) )
  2018.                 return cc;
  2019.             if ( (cc = enc_xdr_int(mp, (void *) &cnt, 1, 1,
  2020.                     (int) sizeof(int))) )
  2021.                 return cc;
  2022.         }
  2023.         return enc_xdr_int(mp, vp, cnt, std, siz);
  2024.     }
  2025.  
  2026.     /* Weasel Hack to Sneak in Trace Markers, with cnt == 0...  :-)   */
  2027.     /* Need to be able to insert markers without other data type and  */
  2028.     /* array size crapola - it's either this or a new pvm_pkmarker()  */
  2029.     /* routine and an enc_mrk for each encoding (which is more bogus).*/
  2030.     else if ( vp != NULL && *((int *) vp) < 0 ) {
  2031.         return enc_xdr_int(mp, vp, 1, 1, (int) sizeof(int));
  2032.     }
  2033.  
  2034.     return 0;
  2035. }
  2036.  
  2037. static int
  2038. enc_trc_long(mp, vp, cnt, std, siz)
  2039.     struct pmsg *mp;
  2040.     void *vp;
  2041.     int cnt, std, siz;
  2042. {
  2043.     int type;
  2044.     int cc;
  2045.  
  2046.     if ( cnt )
  2047.     {
  2048.         if ( cnt == 1 ) {
  2049.             type = TEV_DATA_LONG | TEV_DATA_SCALAR;
  2050.             if ( (cc = enc_xdr_int(mp, (void *) &type, 1, 1,
  2051.                     (int) sizeof(int))) )
  2052.                 return cc;
  2053.         }
  2054.         else {
  2055.             type = TEV_DATA_LONG | TEV_DATA_ARRAY;
  2056.             if ( (cc = enc_xdr_int(mp, (void *) &type, 1, 1,
  2057.                     (int) sizeof(int))) )
  2058.                 return cc;
  2059.             if ( (cc = enc_xdr_int(mp, (void *) &cnt, 1, 1,
  2060.                     (int) sizeof(int))) )
  2061.                 return cc;
  2062.         }
  2063.         return enc_xdr_long(mp, vp, cnt, std, siz);
  2064.     }
  2065.     return 0;
  2066. }
  2067.  
  2068. static int
  2069. enc_trc_ulong(mp, vp, cnt, std, siz)
  2070.     struct pmsg *mp;
  2071.     void *vp;
  2072.     int cnt, std, siz;
  2073. {
  2074.     int type;
  2075.     int cc;
  2076.  
  2077.     if ( cnt )
  2078.     {
  2079.         if ( cnt == 1 ) {
  2080.             type = TEV_DATA_ULONG | TEV_DATA_SCALAR;
  2081.             if ( (cc = enc_xdr_int(mp, (void *) &type, 1, 1,
  2082.                     (int) sizeof(int))) )
  2083.                 return cc;
  2084.         }
  2085.         else {
  2086.             type = TEV_DATA_ULONG | TEV_DATA_ARRAY;
  2087.             if ( (cc = enc_xdr_int(mp, (void *) &type, 1, 1,
  2088.                     (int) sizeof(int))) )
  2089.                 return cc;
  2090.             if ( (cc = enc_xdr_int(mp, (void *) &cnt, 1, 1,
  2091.                     (int) sizeof(int))) )
  2092.                 return cc;
  2093.         }
  2094. #if    defined(I860_NODE)
  2095.         /* XXX are handwritten anyhow */
  2096.         return enc_xdr_long(mp, vp, cnt, std, siz);
  2097. #else
  2098.         return enc_xdr_ulong(mp, vp, cnt, std, siz);
  2099. #endif
  2100.     }
  2101.     return 0;
  2102. }
  2103.  
  2104. static int
  2105. enc_trc_float(mp, vp, cnt, std, siz)
  2106.     struct pmsg *mp;
  2107.     void *vp;
  2108.     int cnt, std, siz;
  2109. {
  2110.     int type;
  2111.     int cc;
  2112.  
  2113.     if ( cnt )
  2114.     {
  2115.         if ( cnt == 1 ) {
  2116.             type = TEV_DATA_FLOAT | TEV_DATA_SCALAR;
  2117.             if ( (cc = enc_xdr_int(mp, (void *) &type, 1, 1,
  2118.                     (int) sizeof(int))) )
  2119.                 return cc;
  2120.         }
  2121.         else {
  2122.             type = TEV_DATA_FLOAT | TEV_DATA_ARRAY;
  2123.             if ( (cc = enc_xdr_int(mp, (void *) &type, 1, 1,
  2124.                     (int) sizeof(int))) )
  2125.                 return cc;
  2126.             if ( (cc = enc_xdr_int(mp, (void *) &cnt, 1, 1,
  2127.                     (int) sizeof(int))) )
  2128.                 return cc;
  2129.         }
  2130.         return enc_xdr_float(mp, vp, cnt, std, siz);
  2131.     }
  2132.     return 0;
  2133. }
  2134.  
  2135. static int
  2136. enc_trc_double(mp, vp, cnt, std, siz)
  2137.     struct pmsg *mp;
  2138.     void *vp;
  2139.     int cnt, std, siz;
  2140. {
  2141.     int type;
  2142.     int cc;
  2143.  
  2144.     if ( cnt )
  2145.     {
  2146.         if ( cnt == 1 ) {
  2147.             type = TEV_DATA_DOUBLE | TEV_DATA_SCALAR;
  2148.             if ( (cc = enc_xdr_int(mp, (void *) &type, 1, 1,
  2149.                     (int) sizeof(int))) )
  2150.                 return cc;
  2151.         }
  2152.         else {
  2153.             type = TEV_DATA_DOUBLE | TEV_DATA_ARRAY;
  2154.             if ( (cc = enc_xdr_int(mp, (void *) &type, 1, 1,
  2155.                     (int) sizeof(int))) )
  2156.                 return cc;
  2157.             if ( (cc = enc_xdr_int(mp, (void *) &cnt, 1, 1,
  2158.                     (int) sizeof(int))) )
  2159.                 return cc;
  2160.         }
  2161.         return enc_xdr_double(mp, vp, cnt, std, siz);
  2162.     }
  2163.     return 0;
  2164. }
  2165.  
  2166. static int
  2167. enc_trc_cplx(mp, vp, cnt, std, siz)
  2168.     struct pmsg *mp;
  2169.     void *vp;
  2170.     int cnt, std, siz;
  2171. {
  2172.     int type;
  2173.     int cc;
  2174.  
  2175.     if ( cnt )
  2176.     {
  2177.         if ( cnt == 1 ) {
  2178.             type = TEV_DATA_CPLX | TEV_DATA_SCALAR;
  2179.             if ( (cc = enc_xdr_int(mp, (void *) &type, 1, 1,
  2180.                     (int) sizeof(int))) )
  2181.                 return cc;
  2182.         }
  2183.         else {
  2184.             type = TEV_DATA_CPLX | TEV_DATA_ARRAY;
  2185.             if ( (cc = enc_xdr_int(mp, (void *) &type, 1, 1,
  2186.                     (int) sizeof(int))) )
  2187.                 return cc;
  2188.             if ( (cc = enc_xdr_int(mp, (void *) &cnt, 1, 1,
  2189.                     (int) sizeof(int))) )
  2190.                 return cc;
  2191.         }
  2192.         return enc_xdr_cplx(mp, vp, cnt, std, siz);
  2193.     }
  2194.     return 0;
  2195. }
  2196.  
  2197. static int
  2198. enc_trc_dcplx(mp, vp, cnt, std, siz)
  2199.     struct pmsg *mp;
  2200.     void *vp;
  2201.     int cnt, std, siz;
  2202. {
  2203.     int type;
  2204.     int cc;
  2205.  
  2206.     if ( cnt )
  2207.     {
  2208.         if ( cnt == 1 ) {
  2209.             type = TEV_DATA_DCPLX | TEV_DATA_SCALAR;
  2210.             if ( (cc = enc_xdr_int(mp, (void *) &type, 1, 1,
  2211.                     (int) sizeof(int))) )
  2212.                 return cc;
  2213.         }
  2214.         else {
  2215.             type = TEV_DATA_DCPLX | TEV_DATA_ARRAY;
  2216.             if ( (cc = enc_xdr_int(mp, (void *) &type, 1, 1,
  2217.                     (int) sizeof(int))) )
  2218.                 return cc;
  2219.             if ( (cc = enc_xdr_int(mp, (void *) &cnt, 1, 1,
  2220.                     (int) sizeof(int))) )
  2221.                 return cc;
  2222.         }
  2223.         return enc_xdr_dcplx(mp, vp, cnt, std, siz);
  2224.     }
  2225.     return 0;
  2226. }
  2227.  
  2228. static int
  2229. dec_trc_init(mp)
  2230.     struct pmsg *mp;
  2231. {
  2232.     return dec_xdr_init(mp);
  2233. }
  2234.  
  2235. static int
  2236. dec_trc_byte(mp, vp, cnt, std, siz)
  2237.     struct pmsg *mp;
  2238.     void *vp;
  2239.     int cnt, std, siz;
  2240. {
  2241.     return dec_xdr_byte(mp, vp, cnt, std, siz);
  2242. }
  2243.  
  2244. static int
  2245. dec_trc_short(mp, vp, cnt, std, siz)
  2246.     struct pmsg *mp;
  2247.     void *vp;
  2248.     int cnt, std, siz;
  2249. {
  2250.     return dec_xdr_short(mp, vp, cnt, std, siz);
  2251. }
  2252.  
  2253. static int
  2254. dec_trc_int(mp, vp, cnt, std, siz)
  2255.     struct pmsg *mp;
  2256.     void *vp;
  2257.     int cnt, std, siz;
  2258. {
  2259.     return dec_xdr_int(mp, vp, cnt, std, siz);
  2260. }
  2261.  
  2262. static int
  2263. dec_trc_long(mp, vp, cnt, std, siz)
  2264.     struct pmsg *mp;
  2265.     void *vp;
  2266.     int cnt, std, siz;
  2267. {
  2268.     return dec_xdr_long(mp, vp, cnt, std, siz);
  2269. }
  2270.  
  2271. static int
  2272. dec_trc_ushort(mp, vp, cnt, std, siz)
  2273.     struct pmsg *mp;
  2274.     void *vp;
  2275.     int cnt, std, siz;
  2276. {
  2277. #if    defined(I860_NODE)
  2278.     /* XXX are handwritten anyhow */
  2279.     return dec_xdr_short(mp, vp, cnt, std, siz);
  2280. #else
  2281.     return dec_xdr_ushort(mp, vp, cnt, std, siz);
  2282. #endif
  2283. }
  2284.  
  2285. static int
  2286. dec_trc_uint(mp, vp, cnt, std, siz)
  2287.     struct pmsg *mp;
  2288.     void *vp;
  2289.     int cnt, std, siz;
  2290. {
  2291. #if    defined(I860_NODE)
  2292.     /* XXX are handwritten anyhow */
  2293.     return dec_xdr_int(mp, vp, cnt, std, siz);
  2294. #else
  2295.     return dec_xdr_uint(mp, vp, cnt, std, siz);
  2296. #endif
  2297. }
  2298.  
  2299. static int
  2300. dec_trc_ulong(mp, vp, cnt, std, siz)
  2301.     struct pmsg *mp;
  2302.     void *vp;
  2303.     int cnt, std, siz;
  2304. {
  2305. #if    defined(I860_NODE)
  2306.     /* XXX are handwritten anyhow */
  2307.     return dec_xdr_long(mp, vp, cnt, std, siz);
  2308. #else
  2309.     return dec_xdr_ulong(mp, vp, cnt, std, siz);
  2310. #endif
  2311. }
  2312.  
  2313. static int
  2314. dec_trc_float(mp, vp, cnt, std, siz)
  2315.     struct pmsg *mp;
  2316.     void *vp;
  2317.     int cnt, std, siz;
  2318. {
  2319.     return dec_xdr_float(mp, vp, cnt, std, siz);
  2320. }
  2321.  
  2322. static int
  2323. dec_trc_double(mp, vp, cnt, std, siz)
  2324.     struct pmsg *mp;
  2325.     void *vp;
  2326.     int cnt, std, siz;
  2327. {
  2328.     return dec_xdr_double(mp, vp, cnt, std, siz);
  2329. }
  2330.  
  2331. static int
  2332. dec_trc_cplx(mp, vp, cnt, std, siz)
  2333.     struct pmsg *mp;
  2334.     void *vp;
  2335.     int cnt, std, siz;
  2336. {
  2337.     return dec_xdr_cplx(mp, vp, cnt, std, siz);
  2338. }
  2339.  
  2340. static int
  2341. dec_trc_dcplx(mp, vp, cnt, std, siz)
  2342.     struct pmsg *mp;
  2343.     void *vp;
  2344.     int cnt, std, siz;
  2345. {
  2346.     return dec_xdr_dcplx(mp, vp, cnt, std, siz);
  2347. }
  2348.  
  2349.  
  2350. /*******************************************
  2351.  **  Alien (can't do it) en/decoder stub  **
  2352.  **                                       **
  2353.  *******************************************/
  2354.  
  2355. static int
  2356. enc_alien()
  2357. {
  2358.     return PvmBadMsg;
  2359. }
  2360.  
  2361.  
  2362. /****************************
  2363.  **  Encoder switch table  **
  2364.  **                        **
  2365.  ****************************/
  2366.  
  2367. static struct encvec encoders[] = {
  2368.  
  2369.     {    enc_raw_init, dec_raw_init,        /* Raw (native) 0 */
  2370.         enc_raw_any, dec_raw_any,
  2371.         enc_raw_any, dec_raw_any,
  2372.         enc_raw_any, dec_raw_any,
  2373.         enc_raw_any, dec_raw_any,
  2374.         enc_raw_any, dec_raw_any,
  2375.         enc_raw_any, dec_raw_any,
  2376.         enc_raw_any, dec_raw_any,
  2377.         enc_raw_any, dec_raw_any,
  2378.         enc_raw_any, dec_raw_any,
  2379.         enc_raw_any, dec_raw_any,
  2380.         enc_raw_any, dec_raw_any },
  2381.  
  2382.     {    enc_xdr_init, dec_xdr_init,        /* XDR 1 */
  2383.         enc_xdr_byte, dec_xdr_byte,
  2384.         enc_xdr_short, dec_xdr_short,
  2385.         enc_xdr_int, dec_xdr_int,
  2386.         enc_xdr_long, dec_xdr_long,
  2387. #if    defined(I860_NODE)
  2388.         enc_xdr_short, dec_xdr_short,    /* XXX are handwritten anyhow */
  2389.         enc_xdr_int, dec_xdr_int,
  2390.         enc_xdr_long, dec_xdr_long,
  2391. #else
  2392.         enc_xdr_short, dec_xdr_ushort,
  2393.         enc_xdr_int, dec_xdr_uint,
  2394.         enc_xdr_ulong, dec_xdr_ulong,
  2395. #endif
  2396.         enc_xdr_float, dec_xdr_float,
  2397.         enc_xdr_double, dec_xdr_double,
  2398.         enc_xdr_cplx, dec_xdr_cplx,
  2399.         enc_xdr_dcplx, dec_xdr_dcplx },
  2400.  
  2401.     {    enc_inp_init, enc_alien,        /* In place (encode only) 2 */
  2402.         enc_inp_any, enc_alien,
  2403.         enc_inp_any, enc_alien,
  2404.         enc_inp_any, enc_alien,
  2405.         enc_inp_any, enc_alien,
  2406.         enc_inp_any, enc_alien,
  2407.         enc_inp_any, enc_alien,
  2408.         enc_inp_any, enc_alien,
  2409.         enc_inp_any, enc_alien,
  2410.         enc_inp_any, enc_alien,
  2411.         enc_inp_any, enc_alien,
  2412.         enc_inp_any, enc_alien },
  2413.  
  2414.     {    enc_trc_init, dec_trc_init,        /* Trace (a la XDR + annot) 4 */
  2415.         enc_trc_byte, dec_trc_byte,
  2416.         enc_trc_short, dec_trc_short,
  2417.         enc_trc_int, dec_trc_int,
  2418.         enc_trc_long, dec_trc_long,
  2419.         enc_trc_short, dec_trc_ushort,
  2420.         enc_trc_int, dec_trc_uint,
  2421.         enc_trc_ulong, dec_trc_ulong,
  2422.         enc_trc_float, dec_trc_float,
  2423.         enc_trc_double, dec_trc_double,
  2424.         enc_trc_cplx, dec_trc_cplx,
  2425.         enc_trc_dcplx, dec_trc_dcplx },
  2426.  
  2427.     {    enc_alien, dec_raw_init,        /* Alien (can't deal) 5 */
  2428.         enc_alien, dec_raw_any,            /* unpacking bytes allowed */
  2429.         enc_alien, enc_alien,
  2430.         enc_alien, enc_alien,
  2431.         enc_alien, enc_alien,
  2432.         enc_alien, enc_alien,
  2433.         enc_alien, enc_alien,
  2434.         enc_alien, enc_alien,
  2435.         enc_alien, enc_alien,
  2436.         enc_alien, enc_alien,
  2437.         enc_alien, enc_alien,
  2438.         enc_alien, enc_alien },
  2439. };
  2440.  
  2441.  
  2442. /*    pmsg_setlen()
  2443. *
  2444. *    Set m_len field of pmsg (after packing because we don't keep track
  2445. *    of it).
  2446. */
  2447.  
  2448. int
  2449. pmsg_setlen(mp)
  2450.     struct pmsg *mp;
  2451. {
  2452.     struct frag *fp, *fp2;
  2453.     int l = 0;
  2454.  
  2455.     fp = fp2 = mp->m_frag;
  2456.     while ((fp = fp->fr_link) != fp2)
  2457.         l += fp->fr_len;
  2458.     mp->m_len = l;
  2459.     return l;
  2460. }
  2461.  
  2462.  
  2463. /*    pmsg_setenc()
  2464. *
  2465. *    Set encoding parameter for message, initialize encode/decode vector.
  2466. */
  2467.  
  2468. int
  2469. pmsg_setenc(mp, enc)
  2470.     struct pmsg *mp;
  2471.     int enc;
  2472. {
  2473.     mp->m_enc = enc;
  2474.     if (enc == pvmmydsig)        /* native */
  2475.         enc = 0;
  2476.     else if (enc == 0x10000000)    /* xdr */
  2477.         enc = 1;
  2478.     else if (enc == 0x20000000)    /* inplace */
  2479.         enc = 2;
  2480.     else if (enc == 0x40000000) /* trace */
  2481.         enc = 3;
  2482.     else                        /* alien */
  2483.         enc = 4;
  2484.     mp->m_codef = &encoders[enc];
  2485.     return 0;
  2486. }
  2487.  
  2488.  
  2489. int
  2490. pmsg_dump(mp, lvl)
  2491.     struct pmsg *mp;
  2492.     int lvl;            /* 0 - summary, 1 - frag lengths, 2 - frag data */
  2493. {
  2494.     struct frag *fp;
  2495.  
  2496.     if (mp->m_flag & MM_PACK)
  2497.         pmsg_setlen(mp);
  2498. #ifdef    MCHECKSUM
  2499.     pvmlogprintf(
  2500.     "pmsg_dump(0x%x) ref=%d mid=%d len=%d ctx=0x%x tag=%d wid=0x%x src=0x%x dst=0x%x enc=0x%x flag=%d crc=0x%x\n",
  2501.             mp, mp->m_ref, mp->m_mid, mp->m_len,
  2502.             mp->m_ctx, mp->m_tag, mp->m_wid, mp->m_src, mp->m_dst,
  2503.             mp->m_enc, mp->m_flag, pmsg_crc(mp));
  2504.  
  2505. #else
  2506.     pvmlogprintf(
  2507.     "pmsg_dump(0x%x) ref=%d mid=%d len=%d ctx=0x%x tag=%d wid=0x%x src=0x%x dst=0x%x enc=0x%x flag=%d\n",
  2508.             mp, mp->m_ref, mp->m_mid, mp->m_len,
  2509.             mp->m_ctx, mp->m_tag, mp->m_wid, mp->m_src, mp->m_dst,
  2510.             mp->m_enc, mp->m_flag);
  2511. #endif
  2512.     if (lvl > 0) {
  2513.         for (fp = mp->m_frag->fr_link; fp != mp->m_frag; fp = fp->fr_link) {
  2514.             pvmlogprintf(" frag=0x%x max=%d ofs=%d len=%d\n",
  2515.                 fp, fp->fr_max, fp->fr_dat - fp->fr_buf, fp->fr_len);
  2516.             if (lvl > 1)
  2517.                 pvmhdump(fp->fr_dat, fp->fr_len, "  ");
  2518.         }
  2519.     }
  2520.     return 0;
  2521. }
  2522.  
  2523.  
  2524. /*    pmsg_pack()
  2525. *
  2526. *    Pack a message into another message, including header fields.
  2527. */
  2528.  
  2529. int
  2530. pmsg_pack(mp, mp2)
  2531.     struct pmsg *mp;        /* message to pack into */
  2532.     struct pmsg *mp2;        /* message to include */
  2533. {
  2534.     struct frag *fp;
  2535.     int cc;
  2536.  
  2537.     if (mp2->m_flag & MM_PACK)
  2538.         pmsg_setlen(mp2);
  2539.  
  2540.     if (cc = (mp->m_codef->enc_int) (mp, (void*)&mp2->m_len, 1, 1, sizeof(int)))
  2541.         return cc;
  2542.     if (cc = (mp->m_codef->enc_int) (mp, (void*)&mp2->m_ctx, 1, 1, sizeof(int)))
  2543.         return cc;
  2544.     if (cc = (mp->m_codef->enc_int) (mp, (void*)&mp2->m_tag, 1, 1, sizeof(int)))
  2545.         return cc;
  2546.     if (cc = (mp->m_codef->enc_int) (mp, (void*)&mp2->m_wid, 1, 1, sizeof(int)))
  2547.         return cc;
  2548.     if (cc = (mp->m_codef->enc_int) (mp, (void*)&mp2->m_enc, 1, 1, sizeof(int)))
  2549.         return cc;
  2550.     if (cc = (mp->m_codef->enc_int) (mp, (void*)&mp2->m_crc, 1, 1, sizeof(int)))
  2551.         return cc;
  2552.     if (cc = (mp->m_codef->enc_int) (mp, (void*)&mp2->m_src, 1, 1, sizeof(int)))
  2553.         return cc;
  2554.     if (cc = (mp->m_codef->enc_int) (mp, (void*)&mp2->m_dst, 1, 1, sizeof(int)))
  2555.         return cc;
  2556.     if (fp = mp2->m_frag)
  2557.         while ((fp = fp->fr_link) != mp2->m_frag) {
  2558.             if (cc = (mp->m_codef->enc_int)
  2559.                     (mp, (void*)&fp->fr_len, 1, 1, sizeof(int)))
  2560.                 return cc;
  2561.             if (cc = (mp->m_codef->enc_byte)
  2562.                     (mp, (void*)fp->fr_dat, fp->fr_len, 1, 1))
  2563.                 return cc;
  2564.         }
  2565.     return cc;
  2566. }
  2567.  
  2568.  
  2569. /*    pmsg_packbody()
  2570. *
  2571. *    Pack body of a message into another message.
  2572. *    Shares fragments between the messages.
  2573. */
  2574.  
  2575. int
  2576. pmsg_packbody(mp, mp2)
  2577.     struct pmsg *mp;        /* message to pack into */
  2578.     struct pmsg *mp2;        /* message to include body of */
  2579. {
  2580.     struct frag *fp, *fp2;
  2581.     int cc;
  2582.  
  2583.     if (mp->m_enc != mp2->m_enc)
  2584.         cc = PvmMismatch;
  2585.     else {
  2586.         cc = 0;
  2587.         if ((fp = mp2->m_frag) && fp->fr_link != fp) {
  2588.             fp2 = mp->m_frag->fr_rlink;
  2589.             if (fp2 != mp->m_frag && fp2->fr_len == 0) {
  2590.                 LISTDELETE(fp2, fr_link, fr_rlink);
  2591.                 fr_unref(fp2);
  2592.             }
  2593.             while ((fp = fp->fr_link) != mp2->m_frag) {
  2594.                 fp2 = fr_new(0);
  2595.                 fp2->fr_buf = fp->fr_buf;
  2596.                 fp2->fr_max = fp->fr_max;
  2597.                 fp2->fr_dat = fp->fr_dat;
  2598.                 fp2->fr_len = fp->fr_len;
  2599.                 da_ref(fp->fr_buf);
  2600.                 LISTPUTBEFORE(mp->m_frag, fp2, fr_link, fr_rlink);
  2601.             }
  2602.         }
  2603.     }
  2604.     return cc;
  2605. }
  2606.  
  2607.  
  2608. /*    pmsg_unpack()
  2609. *
  2610. *    Unpack a message from a message.
  2611. */
  2612.  
  2613. int
  2614. pmsg_unpack(mp, mp2)
  2615.     struct pmsg *mp;        /* message to unpack from */
  2616.     struct pmsg *mp2;        /* blank message to write on */
  2617. {
  2618.     struct frag *fp;
  2619.     int cc;
  2620.     int mlen;
  2621.     int frl;
  2622.  
  2623.     if (cc = (mp->m_codef->dec_int)
  2624.             (mp, (void*)&mlen, 1, 1, sizeof(int)))
  2625.         return cc;
  2626.     if (cc = (mp->m_codef->dec_int)
  2627.             (mp, (void*)&mp2->m_ctx, 1, 1, sizeof(int)))
  2628.         return cc;
  2629.     if (cc = (mp->m_codef->dec_int)
  2630.             (mp, (void*)&mp2->m_tag, 1, 1, sizeof(int)))
  2631.         return cc;
  2632.     if (cc = (mp->m_codef->dec_int)
  2633.             (mp, (void*)&mp2->m_wid, 1, 1, sizeof(int)))
  2634.         return cc;
  2635.     if (cc = (mp->m_codef->dec_int)
  2636.             (mp, (void*)&mp2->m_enc, 1, 1, sizeof(int)))
  2637.         return cc;
  2638.     if (cc = (mp->m_codef->dec_int)
  2639.             (mp, (void*)&mp2->m_crc, 1, 1, sizeof(int)))
  2640.         return cc;
  2641.     if (cc = (mp->m_codef->dec_int)
  2642.             (mp, (void*)&mp2->m_src, 1, 1, sizeof(int)))
  2643.         return cc;
  2644.     if (cc = (mp->m_codef->dec_int)
  2645.             (mp, (void*)&mp2->m_dst, 1, 1, sizeof(int)))
  2646.         return cc;
  2647.  
  2648.     mp2->m_len = 0;
  2649.  
  2650.     if (mlen < 0)
  2651.         cc = PvmBadMsg;
  2652.     else {
  2653.         while (mlen > 0) {
  2654.             if (cc = (mp->m_codef->dec_int)
  2655.                     (mp, (void*)&frl, 1, 1, sizeof(int)))
  2656.                 break;
  2657.             if (!(fp = fr_new(frl + MAXHDR))) {
  2658.                 cc = PvmNoMem;
  2659.                 break;
  2660.             }
  2661.             fp->fr_dat += MAXHDR;
  2662.             fp->fr_len = frl;
  2663.             if (cc = (mp->m_codef->dec_byte)
  2664.                     (mp, (void*)fp->fr_dat, frl, 1, 1))
  2665.                 break;
  2666.             LISTPUTBEFORE(mp2->m_frag, fp, fr_link, fr_rlink);
  2667.             mp2->m_len += frl;
  2668.             mlen -= frl;
  2669.         }
  2670.         pmsg_setenc(mp2, mp2->m_enc);
  2671.     }
  2672.     return cc;
  2673. }
  2674.  
  2675.  
  2676. /**************************
  2677.  **  Vendor Custom Code  **
  2678.  **                      **
  2679.  **************************/
  2680.  
  2681.  
  2682. #ifdef IMA_CSPP
  2683. static void internal_pre_bcopy(unsigned int, unsigned int, int);
  2684. void read_prefetch_region(unsigned int, int);
  2685.  
  2686. static void
  2687. pre_bcopy(s1, s2, n)
  2688.     unsigned int s1;
  2689.     unsigned int s2;
  2690.     int n;
  2691. {
  2692.     int offset;
  2693.  
  2694.     /* make life easy.  only work on chunks of at least 4 lines */
  2695.     if (n < 320) {
  2696.         read_prefetch_region(s1 & ~0x3f, n + (s1 & 0x3f));
  2697.         BCOPY((void *)s1, (void *)s2, n);
  2698.         return;
  2699.     }
  2700.     /* force starting alignment */
  2701.     offset = (unsigned int)s1 & 0x3f;
  2702.     if (offset) {
  2703.         offset = 64 - offset;
  2704.         BCOPY((void *)s1, (void *)s2, offset);
  2705.         s1 += offset;
  2706.         s2 += offset;
  2707.         n -= offset;
  2708.     }
  2709.  
  2710.     /* deal with case where n is not a multiple of 64 */
  2711.     offset = n & 0x3f;
  2712.     if (offset) {
  2713.         n &= ~0x3f;
  2714.         internal_pre_bcopy(s1, s2, n);
  2715.         s1 += n;
  2716.         s2 += n;
  2717.         BCOPY((void *)s1, (void *)s2, offset);
  2718.         return;
  2719.     }
  2720.  
  2721.     /* n is a multiple of 64 */
  2722.     internal_pre_bcopy(s1, s2, n);
  2723.     return;
  2724. }
  2725.  
  2726. static void
  2727. internal_pre_bcopy(s1, s2, n)
  2728.     unsigned int s1;
  2729.     unsigned int s2;
  2730.     int n;
  2731. {
  2732.     read_prefetch_region(s1, 192);                /* prefetch 0, 1 & 2 */
  2733.     while (1) {
  2734.         read_prefetch_region(s1+192, 64);        /* prefetch 3 */
  2735.         if (n == 256)
  2736.             break;
  2737.         BCOPY((void *)s1, (void *)s2, 64);                        /* copy 0 */
  2738.         s1 += 64; s2 += 64; n -= 64;
  2739.         read_prefetch_region(s1+192, 64);        /* prefetch 0 */
  2740.         if (n == 256)
  2741.             break;
  2742.         BCOPY((void *)s1, (void *)s2, 64);                        /* copy 1 */
  2743.         s1 += 64; s2 += 64; n -= 64;
  2744.         read_prefetch_region(s1+192, 64);        /* prefetch 1 */
  2745.         if (n == 256)
  2746.             break;
  2747.         BCOPY((void *)s1, (void *)s2, 64);                        /* copy 2 */
  2748.         s1 += 64; s2 += 64; n -= 64;
  2749.         read_prefetch_region(s1+192, 64);        /* prefetch 2 */
  2750.         if (n == 256)
  2751.             break;
  2752.         BCOPY((void *)s1, (void *)s2, 64);                        /* copy 3 */
  2753.         s1 += 64; s2 += 64; n -= 64;
  2754.     }
  2755.     BCOPY((void *)s1, (void *)s2, 256); /* last 4 lines */
  2756. }
  2757. #endif
  2758.  
  2759.